Python(3) Cheatsheet
好吧,我还是回来学 Python 了。顺便在这里稍微留一个简易 Cheatsheet 免得再次出现这种要再学一次的惨状。
语法¶
基本¶
语句¶
Python 中每一语句一行,没有语句结束的标识(如 C 中的 ;
)。Line continuation 有两种方式:
显式:在行末使用反斜杠
\
表示语句在这一行没有结束;-
隐式:例如:
续的行的缩进似乎是随意的。( 这里有一份推荐的续行方式指南 ,但(划去)去你的吧我才不记。)
语句块与缩进¶
Python 的语句块以上一行的 :
开始,语句块中每行语句必须以相同的缩进开始,缩进应该叠加,每叠一层语句块增加的缩进不一定相同,如:
标识符¶
Python 的标识符第一个字符不能为 0-9,其余的可为 0-9, A-Z, a-z, _
以及很多其它的 Unicode 字符(如中文),大小写敏感。标识符不能与关键字重合:
False await else import pass None break except in raise True class finally is return and continue for lambda try as def from nonlocal while assert del global not with async elif if or yield
形如 _*
, __*__
, __*
的标识符有特殊意义,之后说明。
语义数据类型¶
这里尝试包括字面值以及一些可以通过特殊语法构造的对象(即不使用普适的类或函数等)。
字符串¶
字面值:详见: String and Bytes literals
# 这两种字符串中不能直接出现换行或是反斜杠或是对应的引号,必须转义 # 当然,也有其它转义字符 str1 = 'string1 with \\ and \n and \' in it' str2 = "string2 with \\ and \n and \" in it" # 这种字符串中只有反斜杠必须转义 longstr1 = '''a normal string''' longstr2 = '''a normal string: ''\'''' # 当然这种情况还是需要做些处理 longstr3 = """another""" longstr4 = """but this is how it is supposed to be used""" # 上面任意一种字符串前都可以加上修饰前缀 # 这里略 somestr1 = r'''raw string with \ as a normal character''' # 相邻字符串会自动连接 concat1= '''Hello ''' "World" # concat1 = "Hello World"
格式化的字符串¶
这个真的太绝望了,脚本语言是吧 Python……其实这个并不是字符串字面值,而是类似于 str.format
的一种包装,是运行时求值的。
到 官方文档这里 拉下去看例子吧。
字节数组¶
可以用类似字符串的方式来表示,使用 b
作为字符串前缀即可,字符串内部只能含有 ASCII 字符。
数字¶
-
整数:中间可以掺杂任意单个的下划线,下划线会被直接忽略。整数是无限精度的。
十进制:非零数字开头;
二进制:
0b
或0B
开头;八进制:
0o
或0O
开头;十六进制:
0x
或0X
开头,十六进制 a-f 不分大小写。
浮点数:
[数字].[数字]
或数字e数字
的格式,e
大小写均可。虚数/复数: 在普通数字后加后缀
j
或J
表示虚数单位,可以加上一个实数表示复数。
序列¶
字符串、字节数组也属于序列。
天哪,我举例子吧……
a = (1, 2, 3) b = (1, ) c = [1, 2, 3] d = (*a, ) # d = (1, 2, 3) e = [*a, 4] # e = [1, 2, 3, 4] f = {*a} # f = {1, 2, 3} g = {"a": 1, "b": 2} h = {**g, "c": 3} # h = {"a": 1, "b": 2, "c": 3} i = [(x, y) for x in range(1, 4) for y in range(3, 5) if x == y] # i = [(3, 3)] j = {(x, y) for x in range(1, 4) for y in range(3, 5) if x == y} # j = {(3, 3)} k = {x: y for x in range(1, 4) for y in range(3, 5) if x == y} # k = {3: 3}
元组¶
内含有逗号 ,
的括号 ()
会被解释为元组(tuple),有时候无需括号也可以生成元组。
列表¶
陈列(Display)¶
Lambda¶
一些内建常值类型¶
None:
None
NotImplemented:
NotImplemented
Ellipsis:
Ellipsis
或...
True, False:
True
或False
数据运算与操作¶
似乎 Python 也支持操作符重载了?
下面表格是随便排的序,优先级请多用括号。
加减乘除括号 |
略 |
乘方 |
|
反码 |
|
矩阵相乘? |
|
地板除 |
|
取余数 |
|
printf 式格式化 |
|
位左右移 |
|
大于小于等于 |
同 C |
相同引用 |
|
包含 |
|
布尔操作 |
|
赋值表达式 |
|
条件表达式 |
|
序列操作¶
对于一个序列 seq
,可能的操作:
类似普通数组:
seq[0]
数组反向:
seq[-1]
对于 dict:
seq["key"]
-
Slicing:例如普通 list:
序号取 1 到 3 (在 4 前停)共 3 个元素:
seq[1:4]
1 开始取,序号每递增 2,在 4 前停:
seq[1:4:2]
Slicing:例如某些矩阵(?):
seq[1:4, 2:4]
差不多就那意思
流程控制语句¶
return
, yield
, break
, continue
, raise
这些先略过。
if
:
while
:
for
:
函数¶
函数定义时的参数顺序大概是:
def foo( pos1, pos2, # 位置参数 /, # 强制不能使用 foo(pos1=...) # 来调用函数 # pos1 的值只能通过位置指定 named1, named2="default", # 此后的参数可以使用关键词参数 *otherpos, # 收集多余的位置参数 # 可以将 otherpos 这一名称省略 # 此时变为 def foo(..., *, ...) # 意为星号后必须为关键词参数 # 不能这样用 def foo(*) named3, named4="default", # 前面星号这里强制使用 foo(name3=...) # 来指定 name3, name4 的值 **othernamed): # 收集多余的关键词参数 pass
摘录并翻译一下文档的一段话: https://docs.python.org/3/reference/expressions.html#calls
首先,生成一个还未填进参数的列表。如果有 N 个位置参数(positional arguments),那么这 N 个参数就先填进列表的最开头。 然后,对于每一个关键词参数(keyword argument),先用参数标识找到其在列表中对应的位置。 如果关键词参数对应的位置已填入了参数,那么抛出
TypeError
异常。否则,将值填进列表中。 处理完后,如果列表还有参数没有填入值的话,使用默认值;如没有默认值,则抛出TypeError
错误。如果位置参数比正式参数(formal parameters)多,则抛出
TypeError
异常。(除非存在*identifier
的正式参数,此时此参数将会接收到一个含有多余参数的 tuple,此参数默认为空 tuple。) 如果某个关键词参数的标识没有对应任一个正式参数的名称的话,抛出TypeError
异常。(除非存在**identifier
的正式参数,此时此参数将会接收到一个含有多余参数的 dictionary,此参数默认为空 dictionary。)
(天哪……躺平)
lambda¶
前面已有。
面对对象¶
特殊名字的成员函数¶
Python 的面对对象的东西(几乎)全部基于具有特殊名字的函数。关键字里 private
, protected
没有的。行吧。
__*
这样的名称是私有的成员。
类中的函数(一般)要包涵个 self
参数。
-
生命周期:
__new__
__init__
__del__
-
类型转换:
__repr__
__str__
__bytes__
__format__
__bool__
__hash__
-
比较运算:
__lt__
__le__
__eq__
__ne__
__gt__
__ge__
-
类的功能性:(meta?)
__getattr__
__getattribute__
__setattr__
__delattr__
__dir__
__get__
__set__
__delete__
__set_name__
__init_subclass__
…
-
与内建函数有关?:
__len__
-
模仿可调用的对象:
__call__
-
模仿可取下标的对象:
-
类本身取下标:(
class[i]
这样)__class_getitem__
-
容器类:
__getitem__
__length_hint__
__getitem__
__setitem__
__delitem__
__missing__
__iter__
__reversed__
__contains__
-
模仿数字类型: https://docs.python.org/3/reference/datamodel.html#emulating-numeric-types
啊我不管了 https://docs.python.org/3/reference/datamodel.html#special-method-names
全局函数(?)¶
下面名称后没有跟括号的就表示用法过多略了。但一般还是比较符合直觉的?
abs(-11) # 11 all([True, True, False]) # False any([True, True, False]) # True ascii('中文') # "'\\u4e2d\\u6587'" bin(3) # '0b11' bool('A') # True breakpoint() # 用法过多略 bytearray # 创建 bytearray bytes # 创建 bytes callable(lambda x:x) # True chr(8364) # '€' @classmethod # 是个 decorator compile # 如其名,复杂 complex(1, 2)+complex('0+1j') # (1+3j) delattr(x, 'foobar') # 同 del x.foobar dict # 创建 dict dir # 列举属性 divmod(7, 3) # (2, 1) enumerate # yield (n, elem) for elem in seq eval # 如名 exec # 和 eval 是同一类的? filter(lambda x: x>5, [5, 6]) # list(_) == [6] float # 创建 float format # 返回格式化的字符串 frozenset # 创建 frozenset getattr(x, 'foobar', "default") # 不解释 globals() # 返回当前全局符号表 hasattr(x, 'foobar') # 不解释 hash(x) # 不解释 help # 恩 hex(255) # '0xff' id # 略 input('请输入') # _ == 输入的内容 int # 创建 int,可使用 base 参数 isinstance(object, class)# 恩 issubclass(class, class1)# 恩 iter # 创建对应的 iter len # length list # 创建 list locals() # 返回当前局域符号表 map(lambda x: x+1, [3, 4, 5]) # list(_) == [4, 5, 6] max # 恩 memoryview # 不懂 min # 恩 next(iterator, default) # 恩 object # 创建 object oct(8) # '0o10' open # fopen 多一点 ord('a') # 97 pow(base, exp [,mod]) # 乘方,mod 参数是为了计算效率 print # 恩 property # 额设置 getter setter? range # range(10) == range(0, 10, 1) repr # 返回对象的表示,最好可以再用 eval 还原 reversed # 创建反向 iter round(number [,ndigits]) # 四舍五入 set # 创建 set setattr(x, 'foobar', 10) # 不解释 slice # 创建 slice,与 range 差不多 sorted # 排序,一般不应该叫 sort 吗 @staticmethod # decorator 不懂 str # 创建 str sum(iterable [,start]) # 恩 super # 在类函数中返回上级类,可加一些参数 tuple # 创建 tuple type # 返回/创建一个类/类型 vars # 返回 __dict__ zip # 不懂 __import__ # 见后续模块系统
模块系统¶
之后用到再补充。
异常系统¶
x = 5 y = 0 try: z = x/y raise AssertionError() from Exception() except ZeroDivisionError as e: print('Error: ', e) except: print('Catches all other errors') else: print('No exceptions') finally: z = 0 print(z)
内建异常类型¶
额这里就不摘录了。 https://docs.python.org/3/library/exceptions.html#base-classes
常用库¶
之后用到再慢慢补充。基本还是到官方文档去查看库的详细内容为好。
math¶
这个不用说了。
time¶
https://docs.python.org/3/library/time.html
和时间有关的函数。值得一提的是 sleep
在这个库里。
threading¶
https://docs.python.org/3/library/threading.html
多线程相关。用到比较多的应该是里面的 Thread 类。
asyncio¶
要用到 async
和 await
关键字。 async
用于定义异步函数, await
用于等待本应异步的函数的返回。
异步函数执行返回的结果是一个 coroutine
对象,需要使用库函数或 await
才能真正执行:
库本身的函数: - asyncio.sleep(seconds)
: 等待秒数,常与 await
连用; - asyncio.run(async_func())
: 执行一个 coroutine
对象,但不等待; - asyncio.create_task(async_func())
: 执行一个 coroutine
对象,并返回一个 Task
对象, Task
对象可以用于后续的 await
或者用于取消该任务(但是实际上 create_task
后任务已经可能执行了,所以取消不一定有什么用?); - asyncio.gather(co1, ..., future1, ...)
: 将一系列的 coroutine
等对象执行,返回对应的 future
对象,返回值为系列返回值的列表;
要注意的是,因为程序其实还是单线程,所以如果有 input()
等的阻断式操作,整个逻辑大概就会死得很惨。可以看这里: Prompt for user input using python asyncio.create_server instance
subprocess¶
import subprocess process = subprocess.Popen(executablePath, stdout=subprocess.PIPE, universal_newlines=True) while True: line = process.stdout.readline() # process output line if something(): break process.terminate() # import os # import signal # os.kill(process.pid, signal.SIGINT) # if process captures SIGINT for some reason
评论