Python 基础 介绍 什么是 Python
解释性的脚本语言:通过解释器来直接运行,不需要编译链接成二进制文件
动态类型语言:类型在运行时确定,不需要通过代码明文规定
面向对象语言:Python 中一切皆对象
参考资料
使用 安装 建议使用 Miniconda3 安装
运行
在终端执行 Python 代码,用于快速测试一些代码片段或进行简单的计算
1 python -c "print('hello world')"
1 2 3 4 5 6 7 8 9 python -m venv venv python -m pip install <package> python -m SimpleHTTPServer port python -m http.server port
工具
1 2 3 4 5 6 pip install argcomplete activate-global-python-argcomplete eval "$(register-python-argcomplete my-python-app) "
1 2 3 4 5 import click@click.command() @click.argument() @click.option()
语法 查看帮助 注:和 dir()
函数相比,__all__
变量在查看指定模块成员时,它不会显示模块中的特殊成员,同时还会根据成员的名称进行排序显示
1 2 3 4 5 6 7 8 9 10 11 12 13 import numpy as npdir (np)print (np.__all__)help (numpy)help (np)help (np.array)print (np.array.__doc__)
变量
动态类型,不需要规定类型(可通过 变量名: 类型 = 内容
来进行类型标注)
1 2 3 4 x = 3 a: int = 3 PI = 3.14 _ = 3
数据类型 列表 内部元素不要求同一类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 lst = [4 , 5 , 1 , 7 , 2 , 9 ] lst[1 ] lst[-2 ] 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) lst.sort() sorted (lst) lst.reverse() lst[::-1 ] len (lst) sum (lst) 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 ]
元组 可以看成元素不可变的列表,内部也可以包含不同类型的元素
注:元组的生成速度比列表快很多,遍历速度快一点,索引速度差不多
1 2 3 4 5 6 7 8 9 10 11 12 13 14 t = (10 , 1 , 3 , 5 , 9 ) t[1 ] t[1 :3 ] t = (10 ,) t = (10 ) tuple (lst) tuple (i**2 for i in range (1 , 10 ))(i**2 for i in range (1 , 10 ))
字典 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 d = {key: value,} d = {} d = dict (key=value) d.keys() d.values() d.items() d[key] d.get(key) d.get(key, default) d[key] = value del d[key] d.update(d2) d2 = {key: value, **d} from collections import OrderedDictimport ast; ast.literal_eval(str (d1)){k: v for k, v in d.items()} 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(): ... for item in d.items(): ... for key, value in d.items(): ...
集合 无序序列,因此会自动去重;集合放入的元素只能是不可变的对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 s = {1 , 2 , 3 , 1 } s = set () s = set (lst) s1 & s2 s1 | s2 s1 - s2 s1 ^ s2 s2 <= s1 s.add(5 ) s.update([5 , 6 ]) s.remove(1 ) s.discard(10 ) s.pop()
字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 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 ("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
,然后在字符串中用 {}
包含变量或表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 a = 5 b = 10 result = f"{a} + {b} : {a + b} ." print (f"awk '{{print $0}}' file" ):[填充字符][对齐方式][宽度] :.n :+ :- : :[宽度].[精度]f :[填充字符][宽度]d
布尔类型
运算
可以使用 & | 来表示与和或(但并不会短路)
一般使用 and or not 进行与 / 或 / 非运算(会短路)
条件分支 布尔表达式 1 2 3 4 5 6 if value in lst: ... if value not in lst: ...
条件语句
类三目运算符写法 a if condition else b
循环
1 2 3 4 5 6 7 8 9 10 11 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 ))
元素解包
赋值时等号左侧可以是用逗号分隔的多个值,这时会将右侧解包分别赋值给左侧的各个变量
右侧也可以是多个值(只要出现逗号就会视为一个元组)
星号表达式
可以用来在可迭代对象内部解包
也可用来标记一个变量包含多个值
for 循环可以解包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 t = (1 , 2 , 3 ) a, b, c = t t = (1 , 2 , (3 , 4 )) a, b, (c, d) = t l = [1 , 2 , *[3 , 4 ]] a, *b = [1 , 2 , 3 , 4 ] lst = [[1 , 2 ], [3 , 4 ]] for a, b in lst: ...
enumerate 计数
zip 同时循环多个可迭代对象
1 2 3 4 5 6 7 8 for i, value in enumerate (lst, start=...): ... for a, b in zip (lst1, lst2): ...
函数 函数定义与返回值
使用 def
关键字来定义函数;先函数名,然后括号列出参数,下面接代码块
使用 return
返回
没有 return
运行到结尾,返回 None
只有 return
,返回 None
return
后接内容,返回内容
return
的值类型不要求一致
return
可以返回多个值(利用元组)
1 2 3 4 5 6 7 8 def func (... ): ... return ...
函数参数与调用
在 Python 中,*args
和 **kwargs
是用来传递可变数量参数的机制,允许编写灵活的函数(在 Matplotlib 包中这两个参数出现的概率较大,绘图所需参数很多)
单个 *
星号用于指定所有后续参数必须作为关键字参数传递
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 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 输入 : 输出表达式
可以有多个输入
可以将一个函数赋值给一个变量
1 2 3 4 5 6 7 8 9 10 11 12 lambda a: a**2 + 2 *a + 1 (lambda a: a**2 + 2 *a + 1 )(2 ) lambda a, b: a*2 + bf = 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
返回
1 2 3 4 5 6 7 8 def add (x, y, f ): return f(x) + f(y) print (add(-5 , 6 , abs ))list (map (lambda x: x * 2 , [1 , 2 ])) list (map (str , [1 , 2 , 3 ])) list (filter (lambda x: x > 1 , [1 , 2 , 3 ]))
1 2 3 4 f = abs abs = 10 abs (-10 )
main 函数
防止导入时运行代码,只允许直接运行脚本时运行
通过判断 __name__
:若是直接运行,则其等于字符串 main;若是被导入的,则其等于模块名
1 2 3 4 5 6 7 8 9 10 11 12 ... if __name__ == "__main__" : print ("hello" ) else : print (__name__) import script $ python script.py
用户输入
读取用户输入使用内置的 input 函数
函数参数为要显示的提示符,例如 input (“> “)
函数的返回值为一个字符串
每次读入一行(即读到换行为止
类
类可以看成包含一些属性 和方法 的框架
根据类来创建对象 -> 实例化
用 class 关键字来定义类,类的名称 ClassName 通常采用 CamelCase
记法
类的方法:实例方法、类方法、静态方法
实例方法:必须有 self
作为第一个参数(self
可以写成别的,如 this
或 s
等),用于访问实例属性和其他方法
类方法:
使用 @classmethod
装饰器;通常以 cls
作为第一个参数,表示类本身
类方法是与类相关联的方法,而不是与类的实例相关联的方法
可访问类的属性和调用其他类方法,但不能直接访问实例属性(不具有对实例的引用)
可通过类本身进行调用,而不需要创建类的实例
静态方法:使用 @staticmethod
装饰器;不接收 self
或 cls
作为参数;适用于与类相关但不需要访问类或实例属性的方法
构造方法:__init__()
,在类实例化时会被自动调用;用于设置实例属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 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)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 dir () isinstance () @property @attr.setter __init__() __str__() __repr__() __len__() __add__() __class__ __name__
继承与多态
继承:允许一个类(子类)继承另一个类(父类)的属性和方法,实现代码重用和扩展。Python 支持单继承和多继承
方法重写:子类可以重写父类的方法,以实现不同的行为
多态:指的是不同类的对象可以通过相同的接口调用不同的实现。结合继承和方法重写实现
装饰器 装饰器:作用对象是函数,作用是在调用函数之前和之后,为函数添加额外功能
函数装饰器
对函数使用装饰器,会导致函数的 __name__
、__doc__
等属性发生改变,保留原函数的名称等属性,需通过使用内置模块 functools 中的 wraps 来保留函数的元信息
1 2 3 4 5 6 7 8 9 10 11 12 13 from functools import wrapsdef XXX (func ): @wraps(func ) def wrapper (): func() ... return wrapper @XXX def ...
类装饰器
文件 IO
1 2 3 4 5 6 7 8 9 with open ("file" , "r" , encoding="utf-8" ) as f: s = f.read() ... print (f.closed) with open (file, "r" ) as f: lines = f.readlines()
1 2 3 4 5 6 7 8 9 10 import jsonjson_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)
1 2 3 4 5 6 7 8 9 10 import yamlyaml_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)
异常
Python进阶笔记.md
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 BaseException SystemExit KeyboardInterrupt Exception StopIteration GeneratorExit StandardError ArithmeticError FloattingPointError OverflowError ZeroDivisionError AssertionError AttributeError EOFError EnvironmentError IOError OSError WindowsError ImportError LookupError IndexError KeyError MemoryError NameError UnboundLocalError ReferenceError RuntimeError NotImplementedError SyntaxError IndentationError TabError SystemError TypeError ValueError UnicodeError UnicodeDecodeError UnicodeEncodeError UnicodeTranslateError Warning DeprecationWarning FutureWarning OverflowWarning pendingDeprecationWarning RuntimeWarning SysntaxWarning UserWarning
模块 模块导入
模块可以是一个单独的 .py
文件,也可以是一个文件夹(相当于导入其下 __init__.py
文件)
模块中正常编写函数、类、语句
导入时相当于运行了一遍导入的代码
1 2 3 4 5 6 7 8 9 10 11 12 import time time.time() import time as tm tm.time() from time import timetime() from time import *time()
内部模块 Python 自带了很多实用的模块(标准库)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 os sys glob math re datetime subprocess argparse logging hashlib random csv json typing collections tkinter ...
外部模块安装
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 pip install <package> pip install <package>=version pip install -r requirements.txt pip list pip show <package> pip uninstall <package> pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pip install . python setup.py install pip install -e . pip install git+url
文档字符串 docstring
模块开头、函数、类定义下面的三引号字符串
使用 help(...)
或 print(xxx.__doc__)
显示 docstring
使用编辑器 +LSP 时,悬停时会显示 docstirng 用来提示
一些文档生成工具(Sphinx 等)从中获取文档
1 2 3 4 5 6 7 8 9 10 11 12 13 14 """ docstring for module """ def func (... ): """docstring for function""" ... class ClassName : """docstring for class""" def __init__ (self, ... ): """docstring for method""" ...
常用内置模块 os 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import osos.path.expanduser("~" ) os.getenv("HOME" ) os.environ["HOME" ] os.getcwd() os.listdir() os.chdir() os.walk() os.rename(old, new) os.mkdirs() os.makedirs() 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 命令行参数解析
GitHub - omni-us/jsonargparse: Implement minimal boilerplate CLIs derived from type hints and parse from command line, config files and environment variables
命令行参数解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 import argparseparser = argparse.ArgumentParser( prog=..., usage=..., description=..., epilog=..., formatter_class=..., add_help=..., allow_abbrev=..., ) prog usage formatter_class description epilog add_help allow_abbrev argument_default conflict_handler exit_on_error argparse.HelpFormatter argparse.ArgumentDefaultsHelpFormatter argparse.RawTextHelpFormatter parser.description += "..." parser.description += "..." parser.add_argument( "file" , "-f" , "--file" , nargs=..., const=..., default=..., type =..., choices=... required=..., help =..., ) name_or_flags nargs const default type choices required help metavar action store store_true store_false append group = parser.add_argument_group() group = parser.add_mutually_exclusive_group() args = parser.parse_args() file=args.file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 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." , ) ...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 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.
多个子命令的命令行参数解析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import argparseparser = 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() args.func(args) 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import syssys.path.append() 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 1 2 3 4 import shutilshutil.copy() shutil.copytree()
pathlib 1 2 3 4 5 6 7 8 from pathlib import PathTHIS_DIR = Path(__file__).parent Path(...).mkdir(parents=True , exist_ok=True )
subprocess 1 2 3 4 5 6 7 8 9 10 11 import subprocesssubprocess.run( command, shell=True , stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, text=True , capture_output=True , )
re
正则表达式语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 . ^ $ * + ? {n} {n,} {n,m} [abc] [^abc] \d \D \s \S \w \W \b
threading
multiprocessing
dataclasses 使用 @dataclass
装饰器可以自动为类生成几个魔法方法,包括 __init__()
、__repr__()
、__eq__()
等
1 2 3 4 5 6 7 8 9 10 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
1 2 3 4 from pprint import pprintd = {...} pprint(d)
其他 在编程语言中,”foo” 和 “bar” 被广泛应用于各种示例代码中,通常用于表示任意的变量、函数或数据结构。
Python 本身并不直接支持 OpenMP。OpenMP 主要用于 C/C++ 或 Fortran 等语言
GIL(Global Interpreter Lock): 互斥锁,它防止多个线程同时执行 Python 字节码。这意味着即使使用多线程,标准的 Python 解释器也无法实现真正的并行执行。不过,某些操作(如 I/O 或某些库函数)可以释放 GIL
1 2 3 4 5 6 7 8 copy() deepcopy() == is