# 内置函数
- Python 解释器每次启动时,会自动从内置模块 builtins 导入一些内置函数。
- 官方文档 (opens new window)
# 关于输入输出
# print()
print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) -> None
- 功能:将 value 参数的值,输出到终端。
- 如果输入了多个 value 参数,则在它们之间加上一个 sep 值,从而拼接成一个字符串。
- 输出 value 之后,在末尾加上一个 end 值。
- file 参数表示,将 value 输出到哪个文件对象。默认会输出到终端
sys.stdout
,俗称为"打印到终端"。 - flush 参数默认为 False ,表示调用 print() 函数时,不会立即输出到 file ,而是等缓冲了一定体积的字符串之后才输出。
- 例:
>>> print('Hello', end='\n\n') Hello >>> print('Hello', 'World', '!') Hello World !
- 例:显示一个动态进度条这里配置了
>>> for i in range(101): ... print('\rProgress: {:12}{}%'.format((i // 10) * '▇', i), end='', flush=True) ... time.sleep(0.1) ... Progress: ▇▇▇▇▇▇▇▇▇▇ 100%
end=''
,使得每次输出之后不换行,因此可以通过\r
回到行首,重新输出这一行内容。
# input()
input(prompt=None) -> str
- 功能:将 prompt 输出到 stdout ,作为提示语,供用户查看。然后从 stdin 读取一行字符串(由用户键盘输入,会忽略末尾的换行符),将它作为 input() 函数的返回值。
- 例:
>>> a = input('Please input a number: ') Please input a number: 1 >>> a '1' # input() 的返回值为 str 类型 >>> int(a) 1
# 关于执行代码
# exec()
exec(src, globals=..., locals=...) -> None
功能:输入一段 Python 代码,让 Python 解释器执行。
- 可选输入 globals 参数(取值为 dict 类型),决定全局作用域有哪些标识符。默认不输入 globals 参数,会继承当前的全局作用域。
- 可选输入 locals 参数(取值为 dict 类型),决定局部作用域有哪些标识符。默认不输入 locals 参数,会继承当前的局部作用域。
例:
>>> exec('a=0') # 执行 exec() 函数,创建一个变量 a >>> a 0 >>> exec('print(a)', {'a':1}) # 执行 exec() 函数的同时,指定变量 a 的取值 1 >>> a # 在 exec() 函数之外,变量 a 的取值不变 0 >>> exec('print(a)', globals(), locals()) # 执行 exec() 函数的同时,输入当前的所有标识符,默认就会这样做 0
# eval()
eval(src, globals=..., locals=...) -> object
- 功能:输入一个 Python 表达式,让 Python 解释器执行,然后返回表达式的值。
- 对比 exec() 与 eval() 函数:
- exec() 用于执行一段 Python 代码,不考虑返回值。而 eval() 用于执行一个 Python 表达式,并得到其返回值。
>>> exec('1+2') >>> eval('1+2') 3 >>> eval('[print(i) for i in range(3)]') 0 # 这是 print() 打印的内容 1 2 [None, None, None] # 这是 eval() 的返回值
- exec() 可以执行任意类型的 Python 代码,而 eval() 只能执行 Python 表达式。
>>> eval('print(1)') # 可以调用函数 1 >>> eval('a=1') # 不能赋值 SyntaxError: invalid syntax >>> eval('import sys') # 不能导入模块 SyntaxError: invalid syntax
- exec() 中能执行多行 Python 代码(通过分号或换行符作为分隔),而 eval() 不能。
>>> exec('1;2') >>> eval('1;2') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<string>", line 1 1;2 ^ SyntaxError: invalid syntax
- exec() 用于执行一段 Python 代码,不考虑返回值。而 eval() 用于执行一个 Python 表达式,并得到其返回值。
# compile()
compile(src, filename, mode) -> code
- 功能:将 src 编译成一个 code 对象。
- filename 参数表示,从某个文件中读取 src 。
- mode 参数表示编译模式。
- 如果 src 是一个 Python 模块(也就是多行 Python 代码),则应该传入 mode='exec' 。
- 如果 src 是一个 Python 表达式(保存为 str 或 bytes 对象),则应该传入 mode='eval' 。
- 如果 src 是单行 Python 代码(保存为 str 或 bytes 对象),则应该传入 mode='single' 。
- code 对象可以被 exec() 或 eval() 执行。
- 例:
>>> compile('a=1; print(a)', '', 'exec') <code object <module> at 0x00000193EB6BB2F0, file "", line 1> >>> exec(_) 1
# 关于标识符
# help()
help(name)
- 功能:查看一个标识符的说明文档。
- 例:
>>> help(id) Help on built-in function id in module builtins: id(obj, /) Return the identity of an object.
# callable()
callable(name) -> bool
- 功能:判断一个标识符是否可以通过
name()
的语法调用。- 一般情况下,只有函数名、类名可以调用。
- 例:
>>> callable(1) False >>> callable(int) True
# dir()
dir(...) -> list
- 功能:查询某个作用域(也就是某个命名空间)中的所有标识符(包括变量、函数、类、模块等)。
- 直接执行
dir()
,会返回当前作用域的所有标识符:不过这会省略 Python 的内置函数、内置异常名,如果想查看这些标识符,可以执行:>>> dir() ['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> import builtins >>> dir(builtins) ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', ...]
- 执行
dir(object)
,会返回指定对象的所有属性:>>> dir('hello') ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', ...]
# globals()
globals() -> dict
- 功能:查看全局作用域的所有标识符。
- 例:
>>> globals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>}
# locals()
locals() -> dict
- 功能:查看当前作用域的所有标识符。
- 如果在全局作用域执行
locals()
,则相当于执行globals()
:>>> locals() {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>}
- 如果在局部作用域执行
locals()
,则只会看到局部的标识符:>>> def fun1(): ... x = 1 ... print(locals()) ... >>> fun1() {'x': 1}
# vars()
vars() -> dict
vars(obj) -> dict
- 功能:
- 如果不输入参数,则相当于执行
locals()
。>>> vars() == locals() True
- 如果输入一个对象,则读取该对象的
__dict__
内置变量。>>> a = 1 >>> vars(a) TypeError: vars() argument must have __dict__ attribute
- 如果不输入参数,则相当于执行
# 关于类
# isinstance()
isinstance(obj, class_or_tuple) -> bool
- 功能:判断一个对象,是否为某个 class 创建的实例。
- 例:
>>> isinstance(1, float) False >>> isinstance(1, (int, float)) # 可以将多个 class 放在一个 tuple 中,只要匹配其中一个 class ,就返回 True True
# issubclass()
issubclass(cls, class_or_tuple) -> bool
- 功能:判断一个类 cls ,是否为 class_or_tuple 其中一个类,或它们的子孙类。
- 例:
>>> class Test(int): ... pass ... >>> issubclass(Test, Test) True >>> issubclass(Test, float) True >>> issubclass(Test, (int, float)) False
# 关于反射
- 如何访问一个对象的某个成员?
- 一般做法是,使用成员运算符
.
,执行<object>.<meber>
形式的代码。- 这种做法的缺点:编写代码时,就固定了成员的名称,不能改变。
- 例:
>>> 'hello'.encode <built-in method encode of str object at 0x0000025E41188C30>
- 另一种做法:根据某个成员的名称,获取这个成员的引用。名称是一个字符串,可以随时改变。
- 这种做法称为反射(reflection)。
- 大部分编程语言都不支持反射,而 Python 支持反射,体现了它作为一种动态语言的灵活性。
- 一般做法是,使用成员运算符
# getattr()
getattr(obj, name:str, default=...) -> attribute
- 功能:获取对象中,名为 name 的那个属性(又称为成员)。
- 如果不存在该属性,且未传入 default 参数,则抛出异常。
- 如果不存在该属性,且传入了 default 参数,则返回 default 值。
- 例:
>>> a = 'hello' # 创建一个对象,赋值给变量 a >>> getattr(a, 'encode') # 获取对象中,名为 encode 的那个属性 <built-in method encode of str object at 0x0000025E41188C30> >>> _() # 调用 encode() 方法,相当于执行 a.encode() b'hello' >>> getattr(a, 'len') AttributeError: 'str' object has no attribute 'len'
# hasattr()
hasattr(obj, name:str) -> bool
- 功能:判断对象中,是否存在名为 name 的属性。
- 例:
>>> hasattr('hello', 'encode') True >>> hasattr('hello', 'len') False
# setattr()
setattr(obj, name:str, attribute) -> None
功能:在对象中,给名为 name 的那个属性赋值,让它引用 attribute 。
例:
>>> class Test: ... pass ... >>> t1 = Test() >>> setattr(t1, 'name', 't1') # 添加一个名为 name 的属性,它的取值为 't1' 字符串,因此 t1.name 是一个变量 >>> t1.name 't1' >>> setattr(t1, 'print', print) # 添加一个名为 print 的属性,它的取值为 print 函数,因此 t1.print 是一个方法 >>> t1.print('hello') hello
如果声明了类的内置变量
__slots__
,则只允许对指定名称的属性,进行 setattr()、delattr() 操作。>>> class Test: ... __slots__ = ('name', 'method1') ... def method2(self): ... pass ... >>> t1 = Test() >>> setattr(t1, 'name', 't1') # 相当于执行 t1.name = 't1' >>> setattr(t1, 'method1', print) # 相当于执行 t1.method1 = print >>> setattr(t1, 'method2', print) AttributeError: 'Test' object attribute 'method2' is read-only
# delattr()
delattr(obj, name:str) -> None
- 功能:在对象中,删除名为 name 的那个属性。
- 例:
>>> delattr(str(), 'encode') AttributeError: 'str' object attribute 'encode' is read-only
# 关于迭代
# enumerate()
enumerate(iterable, start=0) -> iterable
- 功能:输入一个可迭代对象,枚举其中的所有元素。每迭代一次,就生成一个元组
(n, iterable[n])
,包含序号 n 和第 n 个元素。- start 参数表示,从哪个序号开始迭代。
- 该函数常用于给各个元素添加序号。
- 例:
>>> enumerate('Hello') <enumerate object at 0x0000025E40DC5A40> >>> list(_) [(0, 'H'), (1, 'e'), (2, 'l'), (3, 'l'), (4, 'o')]
# filter()
filter(func=None, iterable) -> iterable
- 功能:遍历 iterable 对象中的所有元素,进行过滤,保留部分元素,然后以迭代器的形式返回。
- 输入一个函数 func 用于决定如何过滤:每迭代一个元素 x ,会调用 func(x) ,如果函数返回值为 True ,才保留该元素。
- 例:
>>> def is_int(x): ... try: ... _ = int(x) ... return True ... except ValueError: ... return False ... >>> iterable = [1, '2', 'three'] >>> filter(is_int, iterable) <filter object at 0x0000025520DDCDC0> >>> list(_) [1, '2']
# range()
range(start: int, stop: int, step: int=1) -> iterable
range(stop: int) -> iterable
功能:生成一个等差数列。从 start 这个数开始,到 stop 这个数结束(不包含 stop 这个数),步进值为 step (即每次递增多少)。
- 输入的这几个参数必须为 int 整型,可以为负数。
- 可以只输入 stop 参数,此时 start 默认值为 0 。
例:
>>> range(5) # range() 的返回值是一个可迭代对象 range(0, 5) >>> list(range(5)) # 可再加一层 list() 进行迭代,展开 range() 中的各个元素 [0, 1, 2, 3, 4] >>> list(range(1, 5)) # 生成一个在 [1, 5) 区间的等差数列 [1, 2, 3, 4] >>> list(range(-1, -10, -2)) # 生成一个在 [-1, -10) 区间、步进值为 -2 的等差数列 [-1, -3, -5, -7, -9]
以下情况中,range() 生成的等差数列为空:
>>> list(range(0)) # stop 不能小于等于 start [] >>> list(range(5, 5)) # stop 不能小于等于 start [] >>> list(range(1, 10, -2)) # 如果 step 为负数,则从 stop 这个数开始反向递增,此时 start 不能小于等于 stop []
# sorted()
sorted(iterable, key: callable=None, reverse=False) -> list
- 功能:输入一个可迭代对象,遍历其中所有元素,按从小到大的顺序,放在一个 list 中返回。
- 如何比较大小?
- 默认是通过
item1 < item2
的方式,比较两个元素的大小。 - 如果用户输入了 key 函数,则会通过
key(item1) < key(item2)
的方式,比较两个元素的大小。
- 默认是通过
- 默认设置了
reverse=False
,表示从小到大,升序排列。
- 如何比较大小?
- 例:
>>> a = [0, 3, 2, 1] >>> sorted(a) [0, 1, 2, 3] >>> sorted(a, key=lambda x:-x) [3, 2, 1, 0] >>> sorted(a, reverse=True) [3, 2, 1, 0]
- 默认是通过比较运算符
<
进行排序,而某些类型的对象之间,不允许比较运算。>>> sorted([1, 'A']) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '<' not supported between instances of 'str' and 'int'
- 例:对字典进行排序
>>> dic = {1:'a', 3:'c', 2:'b'} >>> sorted(dic.keys()) # 迭代字典中所有 key ,进行排序 [1, 2, 3] >>> sorted(dic.items()) # 迭代字典中所有 item ,进行排序。此时每个 item 是二元组 (key, value) ,因此优先根据 key 的大小进行排序 [(1, 'a'), (2, 'b'), (3, 'c')] >>> dict(sorted(dic.items())) # 排序之后再转换成 dict 类型 {1: 'a', 2: 'b', 3: 'c'} >>> dict(sorted(dic.items(), key=lambda item: item[1])) # 提取 item[1] 也就是 value ,根据它的大小进行排序 {1: 'a', 2: 'b', 3: 'c'}
# zip()
zip(*iterable) -> generator
- 功能:
- 该函数接收一个或多个输入参数,每个参数都是一个 iterable 可迭代对象。
- 该函数返回一个生成器,用户每次对它进行迭代,会同时从各个 iterable 输入参数中获取一个元素,组成一个 tuple 然后返回。
- 由于是生成器,用户每对它进行一次迭代,该函数才会对各个 iterable 进行一次迭代,不会提前遍历各个 iterable 的所有元素。
- 例:
>>> zip(range(3)) <zip object at 0x000001A6FA909240> >>> list(_) # 可以用 list() 来迭代,展开 zip() 的返回值 [(0,), (1,), (2,)] >>> list(zip(range(3), 'hello')) # 如果几个 iterable 的可迭代次数不同,则最短的那个 iterable 迭代完毕,就会导致 zip() 函数结束迭代。因此可能遗漏一些元素,没有迭代 [(0, 'h'), (1, 'e'), (2, 'l')] >>> list(zip(*zip(range(3), 'hello'))) # 再加一层 zip(*...) 可以将矩阵恢复原来的顺序 [(0, 1, 2), ('h', 'e', 'l')]
- 使用
itertools.zip_longest()
函数,会保证将所有 iterable 迭代完毕。如果某个 iterable 提前迭代完毕,则后续的每次迭代,该 iterable 都返回 fillvalue 作为值。>>> import itertools >>> itertools.zip_longest(range(3), 'hello', fillvalue=None) <itertools.zip_longest object at 0x0000014CF02C1EA0> >>> list(_) [(0, 'h'), (1, 'e'), (2, 'l'), (None, 'l'), (None, 'o')]
# map()
map(func, *iterable) -> generator
功能:map() 相当于在 zip() 的基础上,增加调用一个用户自定义的 func 函数。相当于以下代码:
def map(func, *iterable): for _tuple in zip(*iterable): yield func(*_tuple)
例:
>>> map(print, range(3), 'hello') <map object at 0x000001A6FACBCF70> >>> list(_) 0 h 1 e 2 l [None, None, None]
例:实现矩阵的转置
>>> list(zip([1, 2, 3, 4], [5, 6, 7])) [(1, 5), (2, 6), (3, 7)] >>> list(map(lambda x, y: (x, y), [1, 2, 3, 4], [5, 6, 7])) [(1, 5), (2, 6), (3, 7)]
# 关于运算
# all()
all(iterable) -> bool
- 功能:输入一个可迭代对象,遍历其中所有元素,检查是否每个元素的 bool 值都为 True 。相当于以下代码:
def all(iterable): for i in iterable: if not i: return False return True
- 例:
>>> all([0, 1, 2]) False >>> all([1, 2]) True >>> all([]) # 如果输入的可迭代对象为空,不包含任何元素,则结果为 True True
# any()
any(iterable) -> bool
- 功能:输入一个可迭代对象,遍历其中所有元素,检查是否存在某一元素的 bool 值为 True 。相当于以下代码:
def any(iterable): for i in iterable: if i: return True return False
- 例:
>>> any([0, 1, 2]) True >>> any([]) # 如果输入的可迭代对象为空,不包含任何元素,则结果为 False False
# len()
len(obj) -> int
- 功能:输入一个对象,返回该对象的长度。实际上是调用内置方法
obj.__len__()
。 - 例:
>>> len('Hello') 5 >>> 'Hello'.__len__() 5
# abs()
abs(number) -> number
- 功能:输入一个数字,返回它的绝对值。
- 例:
>>> abs(-1) 1 >>> abs(-1.0) # 如果输入为 float 类型,则输出也为 float 类型 1.0
# round()
round(number, digits=0) -> number
- 功能:将一个数字的小数部分,进行四舍五入,只保留指定位数。
- 例:
>>> round(123.456) 123 >>> round(123.456, 2) 123.46 >>> round(123.456, 5) # 如果保留的位数,比实际小数位数多,则会返回原数字 123.456 >>> round(123.456, -2) # 保留 -2 位小数,这会对整数部分进行四舍五入 100.0
# max()
max(iterable, key: callable=None) -> value
max(*args, key: callable=None) -> value
- 功能:
- 如果只输入一个参数,则视作 iterable 可迭代对象,遍历其中所有元素,比较大小,然后返回最大的一个元素。
- 如果输入 *args 多个参数,则比较这些参数的大小,然后返回最大值。
- 如何比较大小?
- 默认是通过
item1 < item2
的方式,比较两个元素的大小。 - 如果用户输入了 key 函数,则会通过
key(item1) < key(item2)
的方式,比较两个元素的大小。
- 默认是通过
- 例:
>>> max([1, 2, 3]) 3 >>> max(1, 2, 3) 3
- 例:找到字典中 value 最大的一个 key
>>> dic = {1:'a', 3:'c', 2:'b'} >>> max(dic.keys(), key=dic.get) 3
- 例:找到出现次数最多的一个元素
>>> a = [1, 2, 3, 2] >>> max(set(a), key=a.count) 2
- 如果想统计每个元素的出现次数,建议使用
collections.Counter
。
- 如果想统计每个元素的出现次数,建议使用
# min()
- 功能:min() 函数的用法与 max() 相似,但是返回最小值。
- 例:
>>> min([1, 2, 3]) 1 >>> min(1, 2, 3) 1
# sum()
sum(iterable) -> value
- 功能:输入一个可迭代对象,遍历其中所有元素,将它们通过运算符
+
相加,然后返回总和。 - 例:
>>> sum(range(5)) 10