在函数上定义__getattr__和__getitem__无效

col*_*nta 7 python metaprogramming

免责声明这只是元编程的练习,没有实际意义.

我分配__getitem____getattr__函数对象的方法,但没有效果...

def foo():
  print "foo!"

foo.__getitem__ = lambda name: name
foo.__getattr__ = lambda name: name
foo.baz = 'baz'
Run Code Online (Sandbox Code Playgroud)

我们可以为函数指定属性的完整性检查:

>>> foo.baz
'baz'
Run Code Online (Sandbox Code Playgroud)

整齐."神奇的吸气者"怎么样?

>>> foo.bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'bar'

>>> foo['foo']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'function' object is not subscriptable

>>> getattr(foo, 'bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'bar'
Run Code Online (Sandbox Code Playgroud)

是否有可能在函数对象上有一个"魔术吸气剂"?

col*_*nta 6

不!分配__getitem__给实例不适用于任何类型的对象:

>>> class A(object):
...   pass
...
>>> a = A()
>>> a.__getattr__ = lambda name: name
>>> a.foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'foo'
Run Code Online (Sandbox Code Playgroud)

而且你无法__getattr__在内置函数类型上定义:

>>> import types
>>> types.FunctionType.__getitem__ = lambda name: name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'function'
Run Code Online (Sandbox Code Playgroud)

而且你不能子类types.FunctionType:

>>> import types
>>> class F(types.FunctionType):
...   pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
type 'function' is not an acceptable base type
Run Code Online (Sandbox Code Playgroud)

  • @kindall在下面指出了这一点,但我会在这里提到它,所以它仍然是答案.新式类不使用`__getattr__`及其朋友的"正常"方法解析.`a.foo`在内部翻译为`type(a).__ getattr __('foo')`.因此找不到存储在`a .__ dict__`中的属性`__getattr__`.希望有意义......: - / (2认同)