将__getitem__转发到getattr

3 投票
2 回答
1863 浏览
提问于 2025-04-16 04:04

有人能解释一下这里发生了什么吗?

class Test(object):
    __getitem__ = getattr

t = Test()
t['foo']

在Python 2.7和3.1中会出现错误:

TypeError: getattr expected at least 2 arguments, got 1

而:

def f(*params):
     print params    # or print(params) in 3.1

class Test(object):
    __getitem__ = f

则会打印出我预期的两个参数。

2 个回答

0

getattr这个函数在调用的时候没有传入'self'这个参数,因为它是被分配给了一个对象的属性。

你想要这样做:

__getitem__ = lambda *a, **k: getattr(*a, **k)

这样做会给你想要的输出结果。

6

让人困惑的是,内置函数(还有一些其他类型的可调用对象)在类里面使用时,并不会像普通函数那样变成绑定方法:

>>> class Foo(object): __getitem__ = getattr
>>> Foo().__getitem__
<built-in function getattr>

和下面这个相比:

>>> def ga(*args): return getattr(*args)
>>> class Foo(object): __getitem__ = ga
>>> Foo().__getitem__
<bound method Foo.ga of <__main__.Foo object at 0xb77ad94c>>

所以,getattr没有正确接收到第一个参数('self')。你需要写一个普通的方法来包装它。

撰写回答