函数 用户定义函数 用户定义函数:通过函数定义创建,调用时附带参数列表
函数对象支持获取、设置任意属性
用于给函数附加元数据
使用属性点号.
获取、设置此类属性
特殊属性
__defaults__
:有默认值参数的默认值组成元组
__code__
:编译后 函数体代码对象
__globals__
:存放函数中全局变量的字典的引用
__closure__
:包含函数自由变量 绑定单元的元组
__annotations__
:包含参数注释的字典
字典键为参数名、return
(若包含返回值)
将变量名称(非私有)映射到标注值的特殊字典
若该属性可写、在类或模块体开始执行时,若静态地发现
标注则被自动创建
__kwdefaults__
:keyword-only
参数的默认值字典
大部分可写属性会检查赋值类型
自由变量:上层命名空间中变量,不包括顶级命名空间,即
全局变量不是自由变量
实例/绑定方法 实例/绑定方法:使用属性表示法调用 、定义在类命名空间
中的函数
Py3中以上特性依赖于___getattribute__
实现
属性
绑定方法对象支持只读获取底层函数对象任意属性
但方法属性实际保存在下层函数对象中
所以不能直接设置绑定方法的方法属性,必须在下层函数
对象中显式设置,否则raise AttributeError
绑定方法有两个特殊只读属性
m.__self__
:操作该方法的类实例
m.__func__
:底层实现该方法的函数
m(args,...)
完全等价于m.__func__(m.__self__,args,...)
特殊元属性
__self__
:类对象实例
__func__
:函数对象实例
__doc__
:方法文档,等同于__func__.__doc__
__name__
:方法名,等同于__func__.__name__
__module__
:定义方法所在模块名
Class Method Objects 类方法:提供了始终将类绑定为函数对象首个参数 的方式
对其他对象的封装,通常用于封装用户定义方法对象
会改变从类、类实例获取该对象的方式
用途
实现自定义、多个构造器,如
只调用__new__()
、绕过__init__
,创建未初始化
的实例
反序列化对象:从字节串反序列构造符合要求的对象
通过classmethod()
构造器创建
Py3中以上特性依赖于___getattribute__
实现
Static Method Objects 静态方法:提供了避免将函数对象转换为方法对象 的方式
对任意其他对象的封装,通常用于封装用户定义方法对象
从类、类实例获取静态方法对象时,实际返回的是封装的对象,
不会被进一步转换
静态方法对象自身不是可调用的,但其封装的对象通常可调用
通过内置staticmethod()
构造器创建
Py3中以上特性依赖于___getattribute__
实现
内置函数、方法
内置函数:对C函数的外部封装
内置方法:内置函数另一种形式,(类似实例方法)隐式传入
当前实例作为C函数额外参数
包括以下两种类型
builtin_function_or_method
wrapper_descriptor
参数数量、类型由C函数决定
内置方法由支持其的类型描述
特殊元属性
__self__
:<module 'builtins' (built-in)>
__doc__
:函数/方法文档
__name__
:函数/方法名
__module__
:所在模块名
说明
函数是描述器,函数类function
实现有__get__
方法
function.__get__
即将函数首个参数进行绑定,返回绑定方法
参见cs_python/py3ref/cls_special_methods
Generator Functions 生成器函数:使用yield
语句的函数、方法称为生成器函数
生成器函数调用时返回生成器迭代器对象,控制执行函数体
yield
表达式参见cs_python/py3ref/expressions
Generator-Iterator 生成器迭代器:生成器函数执行得到的迭代器
迭代器协议参见cs_python/py3ref/cls_special_methods
执行过程
其某方法被调用时,生成器函数开始执行
执行到第一个yield表达式被挂起,保留所有局部状态
局部变量当前绑定
指令指针
内部求值栈
任何异常处理状态
返回expression_list
调用生成器某方法,生成函数继续执行
执行return
、函数体执行完毕将raise StopIteration
生成器表达式、yield表达式参见
cs_python/py3ref/expressions
生成器迭代器状态 生成器在声明周期中有如下4中状态
"GEN_CREATED"
:等待执行
"GEN_RUNNING"
:正在执行,只有多线程中才能看到
"GEN_SUSPENDED"
:在yield表达式处挂起状态
"GEN_CLOSED"
:关闭状态
可通过inspect.getgeneratorstate()
方法查看
__next__
1 2 def (pre ) generator .__next__ (): pass
此方法通常隐式通过for
循环、next()
函数调用
send
1 2 def (pre ) generator .send (value ): pass
throw
1 2 def (pre ) generator .throw (type [, value[, traceback]] ): pass
用途:在生成器暂停位置处 引发type
类型异常
若异常被处理:则执行直至下个yield表达式
若生成器函数没有捕获传入异常、或引发另一个异常:异常
会被传播给调用者
返回值:返回生成器产生的下个值(若异常被处理)
若生成器没有产生下个值就退出,raise StopIteration
说明
若生成器中包含子迭代器,throw
传入异常将被传递给
子迭代器
调用throw
启动生成器,会在生成器函数开头引发错误
close
1 2 def (pre ) generator .close (): pass
用途:在生成器函数暂停处raise GeneratorExit
若之后生成器函数正常退出、关闭、引发GeneratorExit
(生成器中未捕获该异常):则关闭生成器并返回调用者
若生成器继续产生值:则raise RuntimeError
若生成器引发其他异常:则传播给调用者
若生成器由于异常、或正常而退出:则无操作
Yield表达式—调用外部函数
当前函数栈保留当前状态、挂起
执行yield表达式“完毕”后,“返回”到调用处
yield表达式“返回值”取决于生成器恢复执行所调用方法
.__next__
:for
、next()
调用,返回None
.send()
:返回.send()
参数
此时整体类似于
主调函数调用生成器函数
生成器函数调用yield表达式
生成器函数—协程
生成器函数类似协程,也被称为semi-coroutine ,是协程子集
相似点
可yield
多次,有多个入口点
执行可以被挂起
可在恢复执行时传递参数控制执行
不同点
yield
后控制权总是转移给生成器迭代器调用者,生成器
函数不能控制yield
后继续执行的位置
(yield
表达式仅仅传递值给父程序,并不是指定需要
跳转的、平等的协程)
生成器函数—try
例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def echo (value=None ): print ("execution start" ) try : while True : try : value = (yield value) except Exception as e: value = e finally : print ("clean up when gen.close() is called" ) if __name__ == "__main__" : gen = echo(1 ) print (next (gen)) print (next (gen)) print (gen.send(2 )) print (gen.throw(TypeError, "spam" )) gen.close()
Coroutine Function 协程函数:使用async def
定义的函数、方法
调用时返回一个coroutine
对象
可能包含await
表达式、async with
、async for
语句
Coroutine Objects 协程对象:属于awaitable 对象
可等待对象参见cs_python/py3ref/cls_special_methods
send
1 2 def (pre ) coroutine .send (value ): pass
throw
1 2 def (pre ) coroutine .throw (type [, value[, traceback]] ): pass
close
1 2 def (pre ) coroutine .close (): pass
用途:清理自身并退出
若协程被挂起,此方法先被委托给导致该协程挂起的迭代器
的.close()
方法,若其存在
然后在挂起点raise GeneratorExit
,使得协程立即清理
自身
最后协程被标记为已结束执行,即使未被启动
协程对象将被销毁时,会被自动调用
Asynchronous Generator Functions 异步生成器函数:包含yield
语句、使用async def
定义函数、
方法(即在协程中)
yield from
表达式在异步生成器函数中使用将引发语法错误
Asynchronous Generator-Iterator 异步生成器迭代器
异步生成器迭代器执行过程、yield表达式、try
结构、同异步
迭代器协议关联, 均参见普通生成器迭代器
异步迭代器协议参见cs_python/py3ref/cls_special_methods
异步生成器函数使用yield from
语句将引发语法错误
最终化处理#todo 处理最终化:事件循环应该定义终结器函数
其接收异步生成器迭代器、且可能调用aclose()
方法并执行
协程
终结器可以通过调用sys.set_asyncgen_hooks()
注册
首次迭代时,异步生成器迭代器将保存已注册终结器以便最终化
时调用
__anext__
1 2 async def (pre ) coroutine agen .__anext__ (): pass
asend
1 2 async def (pre ) coroutine agen .asend (value ): pass
athrow
1 2 async def (pre ) coroutine agen .athrow (type [, value[, traceback]] ): pass
aclose
1 2 async def (pre ) coroutine agen .aclose (): pass
用途:返回可等待对象,可等待对象运行时在异步生成器函数
暂停处raise GeneratorExit
若异步生成器函数正常退出、关闭、引发GeneratorExit
(生成器中未捕获该异常):则运行可等待对象将
raise StopIteration
???
后续调用异步生成器迭代器方法返回其他可等待对象:则
运行可等待对象将raise StopAsyncIteration
若异步生成器函数产生值:则运行可等待对象将
raise RuntimeError
若异步生成器迭代器已经异常、正常退出,则后续调用
aclose
方法将返回无行为可等待对象