Python:itemgetter()返回的函数在类中没有按预期工作

Mic*_*oka 8 python

operator.itemgetter()函数的工作原理是这样的:

>>> import operator
>>> getseconditem = operator.itemgetter(1)
>>> ls = ['a', 'b', 'c', 'd']
>>> getseconditem(ls) 
'b'
Run Code Online (Sandbox Code Playgroud)

编辑我已添加此部分以突出不一致

>>> def myitemgetter(item):
...     def g(obj):
...         return obj[item]
...     return g
>>> mygetseconditem = myitemgetter(1)
Run Code Online (Sandbox Code Playgroud)

现在,我有这门课

>>> class Items(object):
...     second = getseconditem
...     mysecond = mygetseconditem
...
...     def __init__(self, *items):
...         self.items = items
...
...     def __getitem__(self, i):
...         return self.items[i]
Run Code Online (Sandbox Code Playgroud)

使用索引访问第二个项目

>>> obj = Items('a', 'b', 'c', 'd')
>>> obj[1] 
>>> 'b'
Run Code Online (Sandbox Code Playgroud)

通过该mysecond方法访问它也是如此

>>> obj.mysecond()
'b'
Run Code Online (Sandbox Code Playgroud)

但由于某种原因,使用该second()方法会引发异常

>>> obj.second()
TypeError: itemgetter expected 1 arguments, got 0
Run Code Online (Sandbox Code Playgroud)

是什么赋予了?

Rob*_*ers 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)
Run Code Online (Sandbox Code Playgroud)

编辑

编辑问题后,您的意思很清楚.我认为这里发生的是因为getseconditem它不是用户定义的函数,所以在访问时它不会转换为方法obj.second.它只是一个功能.以下内容可在以下网址找到docs:

请注意,每次从类或实例检索属性时,都会发生从函数对象到(未绑定或绑定)方法对象的转换.在某些情况下,卓有成效的优化是将属性分配给局部变量并调用该局部变量. 还要注意,此转换仅适用于用户定义的函数; 在不进行转换的情况下检索其他可调用对象(以及所有不可调用对象).