Python 基础¶
约 2633 个字 863 行代码 预计阅读时间 20 分钟
介绍¶
什么是 Python
- 解释性的脚本语言:通过解释器来直接运行,不需要编译链接成二进制文件
- 动态类型语言:类型在运行时确定,不需要通过代码明文规定
- 面向对象语言:Python 中一切皆对象
参考资料¶
-
GitHub - lijin-THU/notes-python: 中文 Python 笔记(Python 2 版本)
-
Python 速查表
-
GitHub - piglei/one-python-craftsman: 来自一位 Pythonista 的编程经验分享
-
GitHub - scruel/pcc_3e_slides: 《Python 编程:从入门到实践(第三版)》的官方配套图解讲义资源
-
Python tips and tools:GitHub - pablovegan/Python-tips-tools: Short Python tips and tools talk for the Superconducting Qubit Technology school at Benasque 2023.
-
Python Cookbook 3rd Edition Documentation — python3-cookbook 3.0.0 文档
使用¶
安装¶
建议使用 Miniconda3 安装
运行¶
- 在终端运行 Python 脚本
- 指定
UTF-8
编码
# 在 Python 文件的第一行或第二行,指定使用 UTF-8 编码
# 主要用于 Python 2(Python 3 默认使用 UTF-8 编码)
# 方式 1
# -*- coding: utf-8 -*-
# 方式 2
# coding=utf-8
- 在终端执行 Python 代码,用于快速测试一些代码片段或进行简单的计算
- 在终端中使用 Python 模块:
python -m
,通常用于运行可以作为脚本执行的模块,如venv
、pip
等;Python's many command-line utilities - Python Morsels
# 创建虚拟环境
python -m venv venv
# 安装 package
python -m pip install <package>
# 启动 HTTP 服务;可用于临时接收文件
python -m SimpleHTTPServer port # python2
python -m http.server port # python3
- 查看 Python 环境变量
-
Python 在线编译器:Python Online Compiler with all Modules and Versions
-
Python 编译器,可输出可执行文件或扩展模块:GitHub - Nuitka/Nuitka
工具¶
-
Python 版本管理工具:GitHub - pyenv/pyenv: Simple Python version management
-
包管理工具(支持 Python、C++):GitHub - prefix-dev/pixi: Package management made easy
-
Python 包管理工具:GitHub - python-poetry/poetry: Python packaging and dependency management made easy
-
Python docstring 格式化:GitHub - PyCQA/docformatter: Formats docstrings to follow PEP 257
-
Python GitLab API:GitHub - python-gitlab/python-gitlab: A python wrapper for the GitLab API.
-
数据科学 Python(内容感觉一般):GitHub - khuyentran1401/Efficient Python tricks and tools for data scientists
-
将 Python 的计算公式转换成 LaTeX(只能是简单的公式):GitHub - connorferster/handcalcs
-
打印 Python objects:GitHub - gaogaotiantian/objprint
-
将打印的内容以表格的形式呈现:GitHub - astanin/python-tabulate
-
Turtle 模块绘制树:GitHub - Wandrys-dev/FloweringTree: Little tree drawn in Python and Turtle🌲
-
实现按 Tab 键命令自动补全(支持 bash 和 zsh):GitHub - kislyuk/argcomplete: Python and tab completion, better together.
# 安装
pip install argcomplete
activate-global-python-argcomplete
# 激活命令自动补全
eval "$(register-python-argcomplete my-python-app)"
-
检查通过 pip 命令安装的包的 License:GitHub - raimon49/pip-licenses: Dump the license list of packages installed with pip.
-
构建 CLI 工具
- GitHub - tiangolo/typer
- GitHub - google/python-fire
- click:使用装饰器来设置命令的参数和选项
语法¶
查看帮助¶
注:和 dir()
函数相比,__all__
变量在查看指定模块成员时,它不会显示模块中的特殊成员,同时还会根据成员的名称进行排序显示
import numpy as np
# 查看模块/包的方法、属性(成员)
dir(np)
print(np.__all__)
# 查看模块/包及其方法、属性的帮助文档
help(numpy)
help(np)
help(np.array)
print(np.array.__doc__)
变量¶
- 动态类型,不需要规定类型(可通过
变量名: 类型 = 内容
来进行类型标注)
数据类型¶
列表¶
内部元素不要求同一类型
lst = [4, 5, 1, 7, 2, 9]
# 索引
lst[1] # 第二个元素
lst[-2] # 倒数第二个元素
# Python 内置函数,创建切片
slice(start, stop, step)
# 切片(获取列表中的一部分值)
lst[1:4]
lst[:4]
lst[1:]
lst[:] # 整个列表(拷贝一份)
lst[1:4:2] #
lst[4:1:-2] #
lst[::-1] # 列表倒序
# 修改元素
lst[1] = item # 修改元素
# 添加元素
lst.append() # 列表末尾加入元素
# 列表拼接
lst3 = lst + lst2 # 直接相加,不改变原列表,得到新的列表
lst.extend(lst2) # 把一个列表接到当前列表后面
# 排序列表
# 默认从小到大,传入 reverse=True 则从大到小
lst.sort() # 永久排序(即排序后赋值给当前列表)
sorted(lst) # 临时排序,返回排序好的新列表
lst.reverse() # 永久反转
lst[::-1] # 返回反转的列表
# 统计
len(lst) # 列表长度
sum(lst) # 列表元素和;传入 start 参数,指定加和的起始值
max(lst) # 列表最大值
min(lst) # 列表最小值
# 列表推导
lst = [i**2 for i in range(10)]
# 等价于
lst = []
for i in range(10):
lst.append(i**2)
lst1 = [x*y for x in l1 for y in l2]
lst = [i**2 for i in range(10) if i % 2 == 0]
元组¶
可以看成元素不可变的列表,内部也可以包含不同类型的元素
注:元组的生成速度比列表快很多,遍历速度快一点,索引速度差不多
t = (10, 1, 3, 5, 9)
t[1] # 索引
t[1:3] # 切片
t = (10,) # 单个元素的元组
t = (10) # 单个值,类型为 int
tuple(lst) # 将列表转换为元组
# 使用和列表推导类似的方法生成元组
tuple(i**2 for i in range(1, 10))
# 只写 () 则只是生成器表达式
(i**2 for i in range(1, 10))
字典¶
d = {key: value,}
d = {} # 空字典,而非空集合
d = dict(key=value) # dict() 函数
d.keys()
d.values()
d.items()
# 访问键 key 对应的值;可读取、修改
d[key] # 若 key 不存在,会抛出异常
d.get(key) # 返回 None
d.get(key, default) # 返回 default 值
d[key] = value # 添加键值
del d[key] # 删除键值
d.update(d2) # 字典更新
d2 = {key: value, **d} # 在字典首插入键值对
# 有序字典
from collections import OrderedDict
# 将字典字符串还原成 dict
import ast; ast.literal_eval(str(d1))
{k: v for k, v in d.items()}
# 没有内置方法直接通过 value 查找 key
key_specific = [k for k, v in d.items() if v == value_specific][0]
# 使用和列表推导类似的方法生成字典
{key: value for key in ... for value in ... }
# 遍历所有键
for key in d.keys():
...
# 遍历所有值
for value in d.values():
...
# 遍历键值对;item 为元组
for item in d.items():
...
# 将 item 解包
for key, value in d.items():
...
集合¶
无序序列,因此会自动去重;集合放入的元素只能是不可变的对象
s = {1, 2, 3, 1}
s = set() # 空集合
s = set(lst) # 将列表转为集合
s1 & s2 # 交集 s1.intersection(s2)
s1 | s2 # 并集 s1.union(s2)
s1 - s2 # 差集 s1.difference(s2)
s1 ^ s2 # 对称差集 s1.symmetric_difference(s2)
s2 <= s1 # 包含关系 s2.issubset(s1)
s.add(5) # 添加单个元素;若为已有元素,集合不变
s.update([5, 6]) # 添加多个元素
s.remove(1) # 移除单个元素;元素不存在会报错
s.discard(10) # 不会报错
s.pop() # 弹出元素
字符串¶
str = "hello, world"
str1 + str2 # 字符串相加/拼接
str * 3 # 字符串与数字相乘
len(str) # 字符串长度
## 方法
# 分割
str.split(sep) # 按照给定分隔符进行分割得到列表,默认空白
# 连接
lst = ["1", "2", "3"]
" ".join(lst)
# 替换
str.replace(old, new)
# 大小写转换
str.upper() # 转为大写
str.lower() # 转为小写
str.title() # 首字母大写
# 去除多余空格
str.strip() # 去除两端多余空格
str.lstrip() # 删除左侧空格
str.rstrip() # 删除右侧空格
# 多行字符串 用一对 """ 或 ''' 生成
str = """hello, world.
it is a nice day."""
# 代码太长,进行换行
str = "hello, world." \
"it is a nice day."
str(1) # 转换为字符串
repr(1) # 同上
int("1") # 将字符串转换为整数
float(1.0) # 将字符串转换为浮点数
# 格式化字符串
# format() 方法
"{} {} {}".format("a", "b", "c")
# 用数字指定传入参数位置
"{2} {1} {0}".format("a", "b", "c")
# 指定传入参数名称
"{x} {y}".format(y="a", x=1.0)
# 可一起混用
"{y} {0}".format("a", y=1)
# 指定格式
"{:.2f}".format(3.1415)
f-string:一种用于格式化输出字符串的简洁方式;基本语法为:在字符串前加上 f
或 F
,然后在字符串中用 {}
包含变量或表达式
a = 5
b = 10
result = f"{a} + {b}: {a + b}."
# 转义大括号 需写两个 {{
print(f"awk '{{print $0}}' file")
## 格式化语法 f-string format() 通用
# 宽度填充
:[填充字符][对齐方式][宽度] # < 左对齐,> 右对齐,^ 居中
# 字符截断
:.n # 只显示字符串的前 n 个字符
# 数值符号
:+ # 正数加正号、负数加负号
:- # 原样
: # 正数加空格、负数加负号(: 跟的是空格)
# 数值精度
:[宽度].[精度]f # 没有精度默认为 6
:[填充字符][宽度]d # 格式化整数
布尔类型¶
- 运算
- 可以使用 & | 来表示与和或(但并不会短路)
- 一般使用 and or not 进行与 / 或 / 非运算(会短路)
条件分支¶
布尔表达式¶
条件语句¶
- 类三目运算符写法 a if condition else b
- 类似其它语言中的 condition? a: b
循环¶
-
python 中的 for 循环并不像 c 中是指定一个变量的变化方式,而是从列表 / 元组 / 迭代器等可迭代对象中遍历值
-
range()
得到的并不是列表,如果要用其生成列表要使用list(range(...))
# 使用 range 来生成一串数字用来循环
for i in range(10):
pass
for i in range(1, 10):
pass
for i in range(1, 10, 2):
pass
lst = list(range(10)) # 生成列表
元素解包¶
- 赋值时等号左侧可以是用逗号分隔的多个值,这时会将右侧解包分别赋值给左侧的各个变量
- 右侧也可以是多个值(只要出现逗号就会视为一个元组)
- 可以通过 a, b = b, a 实现元素交换
- 星号表达式
- 可以用来在可迭代对象内部解包
- 也可用来标记一个变量包含多个值
- for 循环可以解包
t = (1, 2, 3)
a, b, c = t # a = 1, b = 2, c = 3
t = (1, 2, (3, 4))
a, b, (c, d) = t # c = 3, d = 4
l = [1, 2, *[3, 4]] # [3, 4] 被解包
## l = [1, 2, 3, 4]
a, *b = [1, 2, 3, 4]
## a = 1, b = [2, 3, 4]
lst = [[1, 2], [3, 4]]
for a, b in lst:
... # 第一次循环 a, b 为 1, 2
# 第二次循环 a, b 为 3, 4
- enumerate 计数
- 可以指定初始值
- zip 同时循环多个可迭代对象
for i, value in enumerate(lst, start=...):
...
# a 在 lst1 中循环,b 在 lst2 中循环
# 循环次数为最短的对象的长度
for a, b in zip(lst1, lst2):
...
函数¶
函数定义与返回值¶
- 使用
def
关键字来定义函数;先函数名,然后括号列出参数,下面接代码块 - 使用
return
返回- 没有
return
运行到结尾,返回 None - 只有
return
,返回 None return
后接内容,返回内容return
的值类型不要求一致return
可以返回多个值(利用元组)
- 没有
函数参数与调用¶
- 在 Python 中,
*args
和**kwargs
是用来传递可变数量参数的机制,允许编写灵活的函数(在 Matplotlib 包中这两个参数出现的概率较大,绘图所需参数很多) - 单个
*
星号用于指定所有后续参数必须作为关键字参数传递
def func(a, b):
...
func(1, 3) # 位置参数
func(a=1, b=3) # 关键字参数;顺序可以打乱
def func(a, b=3):
...
func(1) # 默认参数
def func(*args):
...
func(1, 3, 5) # 可变数量的位置参数
func(*[1, 3, 5])
def func(**kwargs):
...
func(a=1, b=3, c=5) # 可变数量的关键字参数
func(**{"a": 1, "b": 3, "c": 5})
def func(*args, **kwargs):
...
func(1, 3, c=5, d=7) # 混合使用
def func(a, *, b, c):
...
func(1, b=3, c=5) # 指定所有后续参数必须作为关键字参数传递
匿名函数¶
- 可以通过 lambda 表达式来定义匿名函数
- lambda 输入 : 输出表达式
- 可以有多个输入
- 可以将一个函数赋值给一个变量
lambda a: a**2 + 2*a + 1
(lambda a: a**2 + 2*a + 1)(2) # 9
lambda a, b: a*2 + b
f = lambda a: a**2 + 2*a + 1
## 近似等价于
def f(a):
return a**2 + 2*a + 1
- 避免用 lambda 赋值的形式定义函数
- 例如 name 属性不会是函数名,而是 "\<lambda>"
高阶函数¶
- 高阶函数:接收函数作为参数的函数;常用的有
map()
、filter()
map()
:接收两个参数,一个是函数,一个是Iterable
,map()
将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator
返回
def add(x, y, f):
return f(x) + f(y)
print(add(-5, 6, abs))
list(map(lambda x: x * 2, [1, 2])) # [2, 4]
list(map(str, [1, 2, 3])) # ["1", "2", "3"]
list(filter(lambda x: x > 1, [1, 2, 3])) # [2, 3]
main 函数¶
- 防止导入时运行代码,只允许直接运行脚本时运行
- 通过判断
__name__
:若是直接运行,则其等于字符串 main;若是被导入的,则其等于模块名
## script.py
...
if __name__ == "__main__":
print("hello")
else:
print(__name__)
import script # 作为模块导入;输出 script
$ python script.py # 直接运行;输出 hello
用户输入¶
- 读取用户输入使用内置的 input 函数
- 函数参数为要显示的提示符,例如 input (“> “)
- 函数的返回值为一个字符串
- 每次读入一行(即读到换行为止
类¶
-
类可以看成包含一些属性和方法的框架
-
根据类来创建对象 -> 实例化
-
用 class 关键字来定义类,类的名称 ClassName 通常采用
CamelCase
记法 -
类的方法:实例方法、类方法、静态方法
-
实例方法:必须有
self
作为第一个参数(self
可以写成别的,如this
或s
等),用于访问实例属性和其他方法 -
类方法:
- 使用
@classmethod
装饰器;通常以cls
作为第一个参数,表示类本身 - 类方法是与类相关联的方法,而不是与类的实例相关联的方法
- 可访问类的属性和调用其他类方法,但不能直接访问实例属性(不具有对实例的引用)
- 可通过类本身进行调用,而不需要创建类的实例
- 使用
-
静态方法:使用
@staticmethod
装饰器;不接收self
或cls
作为参数;适用于与类相关但不需要访问类或实例属性的方法 -
构造方法:
__init__()
,在类实例化时会被自动调用;用于设置实例属性
class ClassName():
"""docstring"""
a = 1
def __init__(self, arg1, arg2):
self.arg1 = arg1
self.arg2 = arg2
def method(self):
print(self.arg1, self.arg2, self.a)
def __str__():
...
def __repr__():
...
@property
@staticmethod
@classmethod
obj = ClassName(2, 3) # 实例化
obj.method() # 使用实例方法
print(obj.a, obj.arg1) # 访问类属性
dir() # 查看类的(实例)所有的属性和方法;函数的所有参数
isinstance() # 在类的初始化函数中对参数的类型进行判别并抛出异常
# 装饰器
@property # 将方法伪装成属性;只读不可写
@attr.setter # 将属性变成可写
# 特殊方法
__init__()
__str__()
__repr__()
__len__()
__add__()
# 特殊属性
__class__
__name__
继承与多态¶
-
继承:允许一个类(子类)继承另一个类(父类)的属性和方法,实现代码重用和扩展。Python 支持单继承和多继承
-
方法重写:子类可以重写父类的方法,以实现不同的行为
-
多态:指的是不同类的对象可以通过相同的接口调用不同的实现。结合继承和方法重写实现
装饰器¶
装饰器:作用对象是函数,作用是在调用函数之前和之后,为函数添加额外功能
函数装饰器
对函数使用装饰器,会导致函数的 __name__
、__doc__
等属性发生改变,保留原函数的名称等属性,需通过使用内置模块 functools 中的 wraps 来保留函数的元信息
from functools import wraps
def XXX(func):
@wraps(func)
def wrapper():
func()
...
return wrapper
@XXX
def ...
类装饰器
- reader writer 装饰器
文件 IO¶
-
with ... as ...
: 开启一个上下文管理器(常用在文件 open 上) -
with
块开始自动打开,with
块结束自动结束;with
块结束后变量仍会留存
with open("file", "r", encoding="utf-8") as f:
s = f.read()
...
print(f.closed) # True
# 行读取
with open(file, "r") as f:
lines = f.readlines()
- 读写 json
import json
json_fn = ...
data = {}
with open(json_fn, "w") as f:
json.dump(data, f, indent=2)
with open(json_fn, "r") as f:
json_data = json.load(f)
- 读写 yaml
import yaml
yaml_fn = ...
yaml_data = {}
with open(yaml_fn, "w") as f:
yaml.safe_dump(yaml_data, f, sort_keys=False)
with open(yaml_fn, 'r') as f:
yaml_data = yaml.safe_load(f)
异常¶
BaseException # 所有异常的基类
SystemExit # 解释器请求退出
KeyboardInterrupt # 用户自行中断执行 ^C
Exception # 常规错误的基类
StopIteration # 迭代器溢出
GeneratorExit # 生成器发生异常后通知退出
StandardError # 所有标准异常类的基类
ArithmeticError # 所有数值计算错误的基类
FloattingPointError # 浮点计算错误
OverflowError # 数值运算溢出
ZeroDivisionError # 除零错误
AssertionError # 断言语句失败
AttributeError # 对象缺失该属性
EOFError # 没有内建输入,到达 EOF 标记
EnvironmentError # 操作系统错误的基类
IOError # 输入/输出操作失败
OSError # 操作系统错误
WindowsError # 系统调用失败
ImportError # 导入模块/对象失败
LookupError # 无效数据查询的基类
IndexError # 序列中没有此索引
KeyError # 映射中没有此键
MemoryError # 内存溢出
NameError # 未声明/初始化对象
UnboundLocalError # 访问未初始化的本地变量
ReferenceError # 试图访问已被回收器回收的对象(弱引用)
RuntimeError # 一般运行时错误
NotImplementedError # 尚未实现的方法
SyntaxError # Python 语法错误
IndentationError # 缩进错误
TabError # Tab 和 Space 混用
SystemError # 一般的解释器系统错误
TypeError # 对类型无效的操作
ValueError # 传入无效的参数
UnicodeError # Unicode 相关错误
UnicodeDecodeError # Unicode 解码时的错误
UnicodeEncodeError # Unicode 编码时的错误
UnicodeTranslateError # Unicode 转码时的错误
Warning # 警告的基类
DeprecationWarning # 关于被弃用的特性的警告
FutureWarning # 关于构造将来语义会有改变的警告
OverflowWarning # 旧的关于自动提升为长整型 (long) 的警告
pendingDeprecationWarning # 关于特性将会被废弃的警告
RuntimeWarning # 可疑的运行时行为的警告
SysntaxWarning # 可疑语法的警告
UserWarning # 用户代码生成的警告
模块¶
模块导入¶
- 模块可以是一个单独的
.py
文件,也可以是一个文件夹(相当于导入其下__init__.py
文件) - 模块中正常编写函数、类、语句
- 导入时相当于运行了一遍导入的代码
# 模块导入
import time
time.time()
import time as tm
tm.time()
from time import time
time()
from time import *
time()
内部模块¶
Python 自带了很多实用的模块(标准库)
os sys # 系统操作
glob # 文件模式匹配
math # 数学运算
re # 正则表达式
datetime # 日期与时间
subprocess # 子进程管理
argparse # 命令行参数解析
logging # 日志记录
hashlib # 哈希计算
random # 随机数
csv json # 数据格式解析
typing # 数据类型
collections # 更多类型
tkinter # Qt
...
外部模块安装¶
-
外部模块(包)可以在 pypi.org 找
-
-e
编辑模式:创建指向项目源代码目录的链接(如site-package/package.egg-link
文件指向源代码pacakge/
目录);源代码的任何更改都会立即反映在 Python 环境中,无需重新安装,方便调试开发
# 使用 pip 安装(pip / python -m pip)
pip install <package> # 安装
pip install <package>=version # 指定版本
pip install -r requirements.txt # 安装 txt 文件中的所有包
pip list # 查看安装的所有包的信息
pip show <package> # 查看某个包的信息
pip uninstall <package> # 卸载包
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple # 换源安装
# pip 安装本地模块
# 目录下需要包含 setup.py / pyproject.toml
pip install . # 安装本地模块(拷贝到 site-packages 中)
python setup.py install # 效果同上
pip install -e . # 以编辑模式安装本地模块
pip install git+url # 使用 Git 从 GitHub 下载源码安装
文档字符串 docstring¶
- 模块开头、函数、类定义下面的三引号字符串
- 使用
help(...)
或print(xxx.__doc__)
显示 docstring - 使用编辑器 +LSP 时,悬停时会显示 docstirng 用来提示
- 一些文档生成工具(Sphinx 等)从中获取文档
"""
docstring for module
"""
def func(...):
"""docstring for function"""
...
class ClassName:
"""docstring for class"""
def __init__(self, ...):
"""docstring for method"""
...
常用内置模块¶
os¶
import os
# 获取 用户根目录路径
os.path.expanduser("~") # 展开 ~
os.getenv("HOME") # 获取环境变量
os.environ["HOME"]
os.getcwd() # 当前路径
os.listdir() # 列出当前路径下的目录/文件
os.chdir() # 切换路径
os.walk() # 遍历路径
os.rename(old, new) # 重命名文件
os.mkdirs() # 创建单层级目录
os.makedirs() # 创建多层级目录;exist_ok=True 目录已存在时,命令不会报错
os.path.exists() # 检查路径是否存在(可以是文件、目录或符号链接等)
os.path.isfile() # 检查路径是否存在且是否为文件
os.path.isdir() # 检查路径是否存在且是否为目录
os.path.basename() # 获取文件路径的文件部分
os.path.dirname() # 获取文件路径的目录部分
os.path.abspath() # 获取绝对路径
os.path.join() # 将各个部分合并成一个路径
os.path.split() # 分离文件路径和文件名
os.path.splitext() # 分离文件名与后缀
argparse¶
命令行参数解析
命令行参数解析¶
- 命令行参数解析
import argparse
# 创建解析器
parser = argparse.ArgumentParser(
prog=...,
usage=...,
description=...,
epilog=...,
formatter_class=...,
add_help=...,
allow_abbrev=...,
)
# ArgumentParser() 参数
prog # 程序名称(可不添加)
usage # 程序使用方法(可不添加)
formatter_class # 自定义帮助文档的输出格式
description # 程序描述
epilog # 在帮助信息结尾添加文本(如作者、版本、联系方式等)
add_help # 是否自动添加 -h/--help 选项
allow_abbrev # 是否允许长选项使用非歧义缩写
argument_default # 所有参数的默认值
conflict_handler # 处理参数名冲突
exit_on_error # 遇到错误时是否应该退出程序
# formatter_class 常用值
argparse.HelpFormatter # 默认
argparse.ArgumentDefaultsHelpFormatter # 显示参数默认值;可选参数设置 default 值后会显示,位置参数需设置 default 和 nargs 才会显示
argparse.RawTextHelpFormatter # 保持原格式
# 若 description 内容很长,可进行以下操作
parser.description += "..."
parser.description += "..."
# 添加参数
parser.add_argument(
"file", # 位置参数;必须提供
"-f", # 可选参数;短选项;可不用空格分隔直接跟参数值
"--file", # 可选参数;长选项
nargs=...,
const=...,
default=...,
type=...,
choices=...
required=...,
help=...,
)
# add_argument() 参数
name_or_flags # 命令行参数名称(位置参数或可选参数)
nargs # 指定命令行中参数应消耗的值的数量;N、?、*、+
const # 常量值(只指定参数但不带值时,使用该 const 值,需结合 nargs=? 使用)
default # 参数的默认值(未指定参数时,使用该 default 值)
type # 该命令行参数应被转换成的类型
choices # 参数的允许值
required # 用于可选参数,默认 False;True 表示该参数必须指定
help # 参数的帮助信息
metavar # 将帮助信息中的参数用 metavar 的值替代(类似占位符)
action # 定义解析命令行选项时,如何处理该选项的值
# action 可选值
store # 默认值,将参数值存储到变量中
store_true # 布尔值开关
store_false # 与 store 相反
append # 将参数值添加到列表中
# 将参数/选项添加到组中
group = parser.add_argument_group()
# 创建互斥的选项组
group = parser.add_mutually_exclusive_group()
# 解析命令行参数
args = parser.parse_args()
# 短、长选项在一起时,需用长选项
file=args.file
- 示例代码:
def get_potcar(...):
...
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Generate VASP, pymatgen recommended POTCAR.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
allow_abbrev=True,
epilog="Author: SLY.",
)
parser.add_argument(
"-pr",
"--psp_recommended",
nargs="?",
const="vasp",
default="vasp",
type=str,
choices=["vasp", "pymatgen"],
help="Recommended pseudopotential source.",
)
parser.add_argument(
"structure_file",
nargs="?",
default="POSCAR",
type=str,
help="Structure file with POSCAR format, eg. POSCAR.",
)
...
- 使用示例
# 可支持的命令行参数
get_potcar.py -h
get_potcar.py
get_potcar.py -pr
get_potcar.py --psp
get_potcar.py --psp_recommended
get_potcar.py -pr pymatgen POSCAR
get_potcar.py --psp pymatgen POSCAR
get_potcar.py --psp_recommended pymatgen POSCAR
# 查看命令行程序描述及使用
usage: get_potcar.py [-h] [-pr [{vasp,pymatgen}]] [structure_file]
Generate VASP, pymatgen recommended POTCAR.
positional arguments:
structure_file Structure file with POSCAR format. (default: POSCAR)
options:
-h, --help show this help message and exit
-pr [{vasp,pymatgen}], --psp_recommended [{vasp,pymatgen}]
Recommended pseudopotential source. (default: vasp)
Author: SLY.
多个子命令的命令行参数解析¶
-
多个子命令的命令行参数解析
import argparse
# 创建解析器
parser = argparse.ArgumentParser()
# 添加子解析器
subparsers = parser.add_subparsers()
# 添加子命令参数
parser_generate = subparsers.add_parser(
"generate",
help="generate atomate optimization workflows.",
)
parser_generate.add_argument(
"-c",
"--character",
type=str,
help="the character of workflow. eg. optimization, static.",
)
# 将一个子命令解析器与一个函数关联
parser_generate.set_defaults(func=wf_relaxation_submit)
parser_get_data = subparsers.add_parser(
"get_data",
help="get data from mongodb."
)
parser_get_data.add_argument(
"-c",
"--character",
type=str,
help="the character of workflow. eg. optimization, static."
)
parser_get_data.set_defaults(func=get_data_mongodb)
# 解析命令行参数并执行
args = parser.parse_args()
# 执行方式 1;简洁
args.func(args)
# 执行方式 2
if hasattr(args, 'func'):
if args.func == wf_relaxation_submit:
return args.func(args)
elif args.func == get_data_mongodb:
return args.func(args)
sys¶
- 可用于简易的命令行参数解析
import sys
sys.path.append() # 添加目录到 PATH 搜索路径
sys.argv # 命令行参数解析
sys.argv[0] # 文件名
def add_two_num(a, b):
return a + b
if __name__ == "__main__":
a = int(sys.argv[1])
b = int(sys.argv[2])
print(add_two_num(a, b))
shutil¶
pathlib¶
from pathlib import Path
# 获取当前脚本文件所在的目录
# __file__ 内置变量,当前脚本的路径
THIS_DIR = Path(__file__).parent
# 创建目录
Path(...).mkdir(parents=True, exist_ok=True)
subprocess¶
# 执行 Shell 命令
import subprocess
subprocess.run(
command, # Shell 命令
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.STDOUT,
text=True,
capture_output=True,
)
re¶
正则表达式语法
# 符号 # 描述
. # 匹配除了换行符之外的任意字符
^ # 匹配字符串的开始
$ # 匹配字符串的结束
* # 匹配前面的子表达式零次或多次
+ # 匹配前面的子表达式一次或多次
? # 匹配前面的子表达式零次或一次
{n} # 精确匹配 n 次
{n,} # 匹配 n 次以上
{n,m} # 匹配 n 至 m 次
[abc] # 匹配方括号内的任一字符
[^abc] # 匹配不在方括号内的任一字符
\d # 匹配数字,等价于 [0-9]
\D # 匹配非数字,等价于 [^0-9]
\s # 匹配任何空白字符,等价于 [\t\n\r\f\v]
\S # 匹配任何非空白字符
\w # 匹配字母数字,等价于 [a-zA-Z0-9_]
\W # 匹配非字母数字
\b # 单词边界
threading¶
multiprocessing¶
dataclasses¶
使用 @dataclass
装饰器可以自动为类生成几个魔法方法,包括 __init__()
、__repr__()
、__eq__()
等
from dataclasses import dataclass
@dataclass
class InventoryItem:
name: str
unit_price: float
quantity_on_hand: int = 0
def total_cost(self) -> float:
return self.unit_price * self.quantity_on_hand
pprint¶
- 以一种格式化和层次清晰的方式输出 dict 内容
其他¶
在编程语言中,"foo" 和 "bar" 被广泛应用于各种示例代码中,通常用于表示任意的变量、函数或数据结构。
Python 本身并不直接支持 OpenMP。OpenMP 主要用于 C/C++ 或 Fortran 等语言
GIL(Global Interpreter Lock): 互斥锁,它防止多个线程同时执行 Python 字节码。这意味着即使使用多线程,标准的 Python 解释器也无法实现真正的并行执行。不过,某些操作(如 I/O 或某些库函数)可以释放 GIL