资讯专栏INFORMATION COLUMN

Python 自定义函数的特殊属性(收藏专用)

zhou_you / 2796人阅读

Python 中通过函数定义所创建的用户自定义函数对象均具有一些特殊属性,需要注意的是这里介绍的是自定义函数(function类型)的特殊属性,而非方法(method 类型)的特殊属性,函数和方法的特熟属性以及默认的返回值可能不尽相同。

对于大多数特殊属性,可以通过下面这个例子示范一下:

class Test():

    def func(self, v = "dog"):
        """这里演示一个闭包函数"""

        name = "dobi"
        def inn_func(age = 1):
            print(name, v, age)

        return inn_func

test = Test()
clsfunc = test.func()

首先看一下方法与函数的区别:实例的函数为bound method,而类的函数以及闭包均为function,需要强调的是 Python 2.x 中类的函数为unbound method,这点与Python 3.x 有所不同,本文则基于 Python 3.51 整理。

print(Test.func)
# 
print(test.func)
# >
print(clsfunc)
# .inn_func at 0x0000020F071D7F28>
__doc__

可写;用于获取函数的文档说明,如果没有,则返回 None

print("Test.func.__doc__:", Test.func.__doc__)
# Test.func.__doc__: 这里演示一个闭包函数
Test.func.__doc__ = "ffffd"  #注意,这里是 Test,不能是 test
print("Test.func.__doc__:", Test.func.__doc__)
# Test.func.__doc__: ffffd
__name__

可写;获取函数的名称。

print("Test.func.__name__:", Test.func.__name__)
# Test.func.__name__: func
Test.func.__name__ = "pet"
print("Test.func.__name__:", Test.func.__name__)
# Test.func.__name__: pet
__qualname__

可写;获取函数的qualname:点示法显示函数名称、所在的类、模块等梯级地址。

print("Test.func.__qualname__:", Test.func.__qualname__)
# Test.func.__qualname__: Test.func
Test.func.__qualname__ = "path"
print("Test.func.__qualname__:", Test.func.__qualname__)
# Test.func.__qualname__: path
__module__

可写;返回函数所在的模块,如果无则返回None

print("Test.func.__module__:", Test.func.__module__)
# Test.func.__module__: __main__
Test.func.__module__ = "a"
print("Test.func.__module__:", Test.func.__module__)
# Test.func.__module__: a
__defaults__

可写;以元组的形式返回函数的默认参数,如果无默认参数则返回None

print("Test.func.__defaults__:", Test.func.__defaults__)
# Test.func.__defaults__: ("dog",)
Test.func.__defaults__ = ("cat",)
print("Test.func.__defaults__:", Test.func.__defaults__)
# Test.func.__defaults__: ("cat",)
print("clsfunc.__defaults__:", clsfunc.__defaults__)
# clsfunc.__defaults__: (1,)
clsfunc.__defaults__ = (2,)
print("clsfunc.__defaults__:", clsfunc.__defaults__)
# clsfunc.__defaults__: (2,)
__code__

可写;返回已编译的函数对象。

print("Test.func.__code__:", Test.func.__code__)
# Test.func.__code__: 

def func2():print("cat")
Test.func.__code__ = func2.__code__
Test.func()
# cat
print("Test.func.__code__:", Test.func.__code__)
# Test.func.__code__: 
__globals__

只读,以字典的形式返回函数所在的全局命名空间所定义的全局变量。

print("Test.func.__globals__:", Test.func.__globals__)
# Test.func.__globals__: {
# "__cached__": None, 
# "Test": , 
# "__builtins__": , 
# "func2": , 
# "__spec__": None, 
# "__doc__": None, 
# "__file__": "D:...a.py", 
# "test": <__main__.Test object at 0x0000020F077E5DA0>, 
# "clsfunc": .inn_func at 0x0000020F071D7F28>, 
# "__package__": None, 
# "__name__": "__main__", 
# "__loader__": <_frozen_importlib_external.SourceFileLoader object at 0x0000020F07289828>
# }
__dict__

可写;以字典的形式返回命名空间所支持的任意自定义的函数属性。

print("Test.func.__dict__:", Test.func.__dict__)
# Test.func.__dict__: {}
__closure__

只读;以包含cell的元组形式返回闭包所包含的自由变量。

print("Test.func.__closure__:", Test.func.__closure__)
# None
print("clsfunc.__closure__:", clsfunc.__closure__)
# clsfunc.__closure__: (
# , 
# 
# )
print("clsfunc.__closure__[x]:", clsfunc.__closure__[0].cell_contents, clsfunc.__closure__[1].cell_contents)
# clsfunc.__closure__[x]: dobi dog
__annotations__

可写;具体详见“Python 的函数注释”

__kwdefaults__

可写,具体详见 “Python 的 Keyword-Only Arguments(强制关键字参数)”

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/45475.html

相关文章

  • ❤️爆肝十二万字《python从零到精通教程》,从零教你变大佬❤️(建议收藏

    文章目录 强烈推荐系列教程,建议学起来!! 一.pycharm下载安装二.python下载安装三.pycharm上配置python四.配置镜像源让你下载嗖嗖的快4.1pycharm内部配置 4.2手动添加镜像源4.3永久配置镜像源 五.插件安装(比如汉化?)5.1自动补码神器第一款5.2汉化pycharm5.3其它插件 六.美女背景七.自定义脚本开头八、这个前言一定要看九、pyt...

    booster 评论0 收藏0
  • Python进阶:迭代器与迭代器切片

    摘要:本文是切片系列的第三篇,主要内容是迭代器切片。实际上,迭代器必然是可迭代对象,但可迭代对象不一定是迭代器。这是迭代器切片最具想象力的用途场景。考虑到文件对象天然就是迭代器,我们可以使用迭代器切片先行截取,然后再处理,如此效率将大大地提升。 2018-12-31 更新声明:切片系列文章本是分三篇写成,现已合并成一篇。合并后,修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章...

    z2xy 评论0 收藏0
  • Python进阶:迭代器与迭代器切片

    摘要:本文是切片系列的第三篇,主要内容是迭代器切片。实际上,迭代器必然是可迭代对象,但可迭代对象不一定是迭代器。这是迭代器切片最具想象力的用途场景。考虑到文件对象天然就是迭代器,我们可以使用迭代器切片先行截取,然后再处理,如此效率将大大地提升。 2018-12-31 更新声明:切片系列文章本是分三篇写成,现已合并成一篇。合并后,修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章...

    hedge_hog 评论0 收藏0
  • Python进阶:迭代器与迭代器切片

    摘要:本文是切片系列的第三篇,主要内容是迭代器切片。实际上,迭代器必然是可迭代对象,但可迭代对象不一定是迭代器。这是迭代器切片最具想象力的用途场景。考虑到文件对象天然就是迭代器,我们可以使用迭代器切片先行截取,然后再处理,如此效率将大大地提升。 2018-12-31 更新声明:切片系列文章本是分三篇写成,现已合并成一篇。合并后,修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章...

    gotham 评论0 收藏0
  • Python进阶:迭代器与迭代器切片

    摘要:本文是切片系列的第三篇,主要内容是迭代器切片。实际上,迭代器必然是可迭代对象,但可迭代对象不一定是迭代器。这是迭代器切片最具想象力的用途场景。考虑到文件对象天然就是迭代器,我们可以使用迭代器切片先行截取,然后再处理,如此效率将大大地提升。 2018-12-31 更新声明:切片系列文章本是分三篇写成,现已合并成一篇。合并后,修正了一些严重的错误(如自定义序列切片的部分),还对行文结构与章...

    omgdog 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<