Python:itemgetter() 返回的函数在类中行为异常
operator.itemgetter() 这个函数的工作原理是这样的:
>>> import operator
>>> getseconditem = operator.itemgetter(1)
>>> ls = ['a', 'b', 'c', 'd']
>>> getseconditem(ls)
'b'
编辑:我添加了这一部分来强调不一致性
>>> def myitemgetter(item):
... def g(obj):
... return obj[item]
... return g
>>> mygetseconditem = myitemgetter(1)
现在,我有了这个类
>>> class Items(object):
... second = getseconditem
... mysecond = mygetseconditem
...
... def __init__(self, *items):
... self.items = items
...
... def __getitem__(self, i):
... return self.items[i]
用索引访问第二个项目是可以的
>>> obj = Items('a', 'b', 'c', 'd')
>>> obj[1]
>>> 'b'
通过 mysecond
方法访问也是可以的
>>> obj.mysecond()
'b'
但是出于某种原因,使用 second()
方法却会引发一个异常
>>> obj.second()
TypeError: itemgetter expected 1 arguments, got 0
这是怎么回事呢?
2 个回答
1
问题似乎出在以下内容:
>>> print (getseconditem, mygetseconditem)
(<operator.itemgetter object at 0x01EE5BD0>, <function g at 0x00504DB0>)
换句话说,一个函数可以被绑定,但一个可调用的东西是不能的。
7
obj.second
是一个名为 getseconditem
的函数。这个函数需要一个参数来进行操作。但是你在调用 obj.second
时没有传入任何参数,所以就出现了你提到的错误。要解决这个问题,你可以这样做:obj.second(obj.items)
,或者你可以以不同的方式定义 second
。
class Items(object):
def __init__(self, *items):
self.items = items
def __getitem__(self, i):
return self.items[i]
def second(self):
return getseconditem(self.items)
编辑
在你编辑了问题后,现在我明白你的意思了。我认为这里发生的事情是,因为 getseconditem
不是一个 用户定义 的函数,所以在访问 obj.second
时,它并不会被转变为一个方法。它仍然只是一个函数。以下内容可以在 docs
中找到:
请注意,从函数对象到(未绑定或绑定的)方法对象的转换发生在每次从类或实例中获取属性时。在某些情况下,一个有效的优化方法是将属性赋值给一个局部变量,然后调用这个局部变量。还要注意,这种转换只发生在用户定义的函数上;其他可调用对象(以及所有不可调用对象)在获取时不会进行转换。