使用setattr()设置特殊方法

7

使用setattr(),可以为类实例动态分配特殊方法,如__getitem__吗?例如,如果我有以下代码:

class Example (object):
    pass

然后尝试这个:

>>> example = Example()
>>> setattr(example, '__getitem__', lambda x: 1)

I get this:

>>> example['something']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Example' object has no attribute '__getitem__'

当然,这个也可以正常工作:
>>> example.__getitem__('something')
1

显然,关于Python如何进行这种类型的方法查找,我还不太理解。这些方法是否必须设置在类上,而不是实例上呢?
更新:我应该明确表示,我知道可以在Example类上看到这个...我希望有一种方法可以按实例设置它们,但目前我看到的共识是你不能这样做。
2个回答

6
这里的问题在于__getitem__()是在类级别而不是实例级别上定义的:
>>> class Example (object):
...     pass
... 
>>> example = Example()
>>> setattr(Example, '__getitem__', lambda x, y: 1)
>>> example['something']
1

如果您需要使其具备实例特定性:

>>> class Example(object):
...     def __getitem__(self, item):
...         return self._getitem(item)
... 
>>> example = Example()
>>> setattr(example, '_getitem', lambda x: 1)
>>> example['something']
1
>>> example2 = Example()
>>> setattr(example2, '_getitem', lambda x: 2)
>>> example['something']
1
>>> example2['something']
2

嗯...但这将影响所有Example的实例,而不仅仅是特定的实例。我想我需要重新考虑一下。 - larsks
@larsks 很容易让 __getitem__() 在实例上调用一个函数。我会添加一个示例。 - Gareth Latty

0
你尝试过对类进行猴子补丁而不是实例吗?
>>> example = Example()
>>> setattr(Example, '__getitem__', lambda self,x: 1)

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