我不确定这到底是什么意思或如何使用,但是当涉及到功能时,我遇到了这个功能。我能够动态地向函数添加属性。
这有什么用,它是如何发生的?我的意思是它毕竟是一个函数名,我们如何动态地向它添加属性?
def impossible():
print "Adding a bool"
impossible.enabled = True
# I was able to just do this. And this is a function, how does this add up?
print(impossible.enabled) # No attribute error. Output: True
在 python 中函数是对象,它们有各种内部属性,它们也可以有
__dict__
属性,和任何其他对象一样,__dict__
中的任何东西都是该对象的变量。如果你打印它,你可以看到它前后impossible.enabled
def impossible():
print "Adding a bool"
print(impossible.__dict__) # {}
impossible.enabled = True
print(impossible.__dict__) # {'enabled': True}
这不会以任何方式改变函数,因为大多数时候
__dict__
是空的并且在函数中没有特殊值。
事实上,它有点用处,因为您可以在函数中使用它来存储静态变量,而不会弄乱您的全局名称
名字
impossible
指向一个代表函数的对象。您正在为此对象设置一个属性(默认情况下 python 允许您对所有对象执行此操作):
>>> def foo():
... print("test")
...
>>> dir(foo)
['__call__', ..., 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
>>> foo.a = 'test'
>>> dir(foo)
['__call__', ..., 'a', ...]
因为这个对象实现了
__call__
,它可以作为一个函数调用——你可以实现你自己的定义__call__
的类,它也可以作为一个函数被调用:
>>> class B:
... def __call__(self, **kw):
... print(kw)
...
>>> b = B()
>>> b()
{}
>>> b(foo='bar')
{'foo': 'bar'}
如果你创建一个新函数,你可以看到你没有对函数(它的类)的定义做任何事情,只是代表原始函数的对象:
>>> def bar():
... print("ost")
...
>>> dir(bar)
['__call__', ..., 'func_closure', ...]
这个新对象没有名为
a
的属性,因为您还没有在bar
指向的对象上设置一个。
例如,您可以使用函数属性来实现一个简单的计数器,如下所示:
def count():
try:
count.counter += 1
except AttributeError:
count.counter = 1
return count.counter
重复调用“count()”产生:1, 2, 3, ...