func
目录
相关位置文件
- cpython/Objects/funcobject.c
- cpython/Include/funcobject.h
- cpython/Objects/clinic/funcobject.c.h
内存构造
在 python 中, 一切皆对象, 包括函数对象, 一个函数对象在 c 语言中被定义为 PyFunctionObject
def f(a, b=2):
print(a, b)
>>> type(f)
function
类型 function 表示用户自定义函数/对象, 对于那种内建函数/对象, 他们是不同的类型, 请参考 method

字段
我们来看看每个字段在 PyFunctionObject 中分别代表什么意思
func_code
func_code 存储了一个 PyCodeObject 的实例, 这个实例会保存一段函数代码块中相关的信息
一段代码块相关信息会包括对应 python 虚拟机的指令, 这个函数的参数数量, 参数内容等信息
后续会有文章讲 PyCodeObject
>>> f.__code__
<code object f at 0x1078015d0, file "<stdin>", line 1>
func_globals
这个函数相关联的全局作用域
>>> type(f.__globals__)
<class 'dict'>
>>> f.__globals__
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'f': <function f at 0x10296eac0>}
func_defaults
一个元组对象, 存储了该函数的所有默参数的值
>>> f.__defaults__
(2,)
func_kwdefaults
func_kwdefaults 是一个 python 字典对象, 保存了指定了默认值的 keyword-only argument
def f2(a, b=4, *x, key=111):
print(a, b, x, key)
>>> f2.__kwdefaults__
{'key': 111}
func_closure
func_closure 是一个元组对象, 存储了当前函数所对应的所有闭包层级
def wrapper(func):
def func_inside(*args, **kwargs):
print("calling func", func)
func(args, kwargs)
print("call done")
return func_inside
@wrapper
def my_func():
print("my func")
>>> my_func.__closure__
(<cell at 0x10911c928: function object at 0x1092b3c40>,)
>>> my_func
<function wrapper.<locals>.func_inside at 0x1092b3b40>
>>> wrapper
<function wrapper at 0x1092b3cc0>
我们来看一个有更多 _closure_ 的示例
def wrapper2(func1):
def func_inside1(func2):
def func_inside2(*args2, **kwargs2):
print("calling func1", func1)
r = func1(*args2, **kwargs2)
print("calling func2", func2)
r = func2(*args2, **kwargs2)
print("call done")
return r
print("func_inside2.__closure__", func_inside2.__closure__)
return func_inside2
print("func_inside1.__closure__", func_inside1.__closure__)
return func_inside1
@wrapper2
def my_func2():
print("my func2")
def func3():
print("func3")
# m = my_func()
inside2 = my_func2(func3)
print("----------------")
inside2()
# output
(<cell at 0x100e69eb8: function object at 0x100e6fea0>,)
func_inside1.__closure__ (<cell at 0x1087e9408: function object at 0x1087f1ae8>,)
func_inside2.__closure__ (<cell at 0x1087e9408: function object at 0x1087f1ae8>, <cell at 0x1087e9498: function object at 0x1087f1bf8>)
----------------
calling func1 <function my_func2 at 0x1087f1ae8>
my func2
calling func2 <function func3 at 0x1087f1bf8>
func3
call done
func_doc
通常, 他是一个用来解释函数作用的 unicode 对象
def f():
"""
I am the document
"""
pass
print(f.__doc__)
func_name
这个 PyFunctionObject 对象的函数名
def i_have_a_very_long_long_long_name():
pass
print(i_have_a_very_long_long_long_name.__name__)
# output
# i_have_a_very_long_long_long_name
func_dict
func_dict 是一个字典对象, 存储了这个对象的属性
>>> f.__dict__
{}
>>> f.a = 3
>>> f.__dict__
{'a': 3}
func_module
func_module 表示了这个对象所属的/相关联的模块
>>> f.__module__
'__main__'
>>> from urllib.parse import urlencode
>>> urlencode.__module__
'urllib.parse'
func_annotations
这是一个比较新的特性, 你可以读一下 PEP 3107 – Function Annotations, 上面有更好的例子解释这个字段的作用
def a(x: "I am a int" = 3, y: "I am a float" = 4) -> "return a list":
pass
>>> a.__annotations__
{'x': 'I am a int', 'y': 'I am a float', 'return': 'return a list'}
func_qualname
这个字段在内嵌函数表示名称的时候挺管用的, 这个字段还包括了从顶往下的内嵌路径, 你可以通过这个字段了解更多函数定义相关的信息, 可以读下 PEP 3155 – Qualified name for classes and functions
def f():
def g():
pass
return g
>>> f.__qualname__
'f'
>>> f().__qualname__
'f.<locals>.g'