内置函数和用户定义函数的不同属性

3

有这样一段代码:

def f():
  pass

print("f: ", dir(f))
print("len: ", dir(len))

输出结果:
f:  ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
len:  ['__call__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

为什么函数f和函数len有不同的属性?我知道len是内置函数,但是为什么它们没有相同的属性呢?

1个回答

9
因为定义在C语言中的函数是不同类型的,只有用户自定义的函数才支持某些功能,例如添加属性或嵌套函数定义并引用作用域名称。请看用户自定义函数提供的额外属性:
>>> sorted(set(dir(f)) - set(dir(len)))
['__annotations__', '__closure__', '__code__', '__defaults__', '__dict__', '__get__', '__globals__', '__kwdefaults__']

一个由C定义的函数不会有闭包、全局变量,也没有字节码。举例来说:

  • __annotations__:函数定义时添加的注释;只有用户定义的函数才能这样做,因为这是Python语法特性。
  • __closure__:从作用域中获取的cell列表;C定义的函数不能在另一个函数内定义,因此对于那些函数没有闭包。
  • __code__:Python的字节码对象;C定义的函数没有这个。
  • __defaults__:C定义的函数可能有默认值(关键字),但它们不被定义为可以反射的Python值。
  • __dict__:C定义的函数不能在其上设置任意属性,而用户定义的函数可以。
  • __get__:这使得用户定义的函数成为描述符,在类中起到方法的作用。大多数C函数不需要这个。
  • __globals__:用户定义的函数在模块中定义;这指向全局命名空间。C定义的函数没有Python模块命名空间可供指向。
  • __kwdefaults__:像__defaults__一样,但用于关键字参数,作为字典;同样只有Python函数才能拥有这些。

@thegrinner:是的,那里出了点问题。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接