想象一下,我的课程Test
有一个属性foo
和一个方法getbar()
。
from operator import attrgetter, methodcaller
class Test(object):
def __init__(self, name, foo):
self.foo = foo
self.name = name
def getbar(self):
""" bar is same value as foo, so should sort identically"""
self.bar = self.foo
def __repr__(self):
return self.name
我会制作一些对象,然后使用attrgetter根据foo
和getbar
的值对它们进行排序。
objs = [Test('a', 5), Test('b', 9), Test('c',20), Test('d', 50)
print 'attrgetter: foo', sorted(objs, key=attrgetter('foo'))
print 'attrgetter: bar', sorted(objs, key=attrgetter('getbar'))
>>>attrgetter: foo [a, b, c, d]
>>>attrgetter: bar [b, a, c, d]
getbar()未正确排序。很公平,但为什么attrgetter
接受一个方法,如果它不能正确排序,就不会抛出错误?
如果传递了某个属性,使用methodcaller
进行排序会引发错误,那么为什么收到方法时不会attrgetter
引发错误?有人可以向我解释这种差异吗?看起来它们应该是对称的。
print 'methodcaller: bar', sorted(objs, key=methodcaller('getbar'))
print 'methodcaller: foo', sorted(objs, key=methodcaller('foo'))
>>>methodcaller: bar [a, b, c, d]
>>>methodcaller: foo
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-2249624f153f> in <module>()
19
20 print 'methodcaller: bar', sorted(objs, key=methodcaller('getbar'))
---> 21 print 'methodcaller: foo', sorted(objs, key=methodcaller('foo'))
TypeError: 'int' object is not callable
答案 0 :(得分:1)
使用
methodcaller
进行排序会在传递属性时引发错误...,那么为什么attrgetter
在收到方法时不会引发错误?
因为在Python中,实例方法是属性。唯一的区别是返回的值是一个绑定方法,通常称之为。
如果你想要两者都有类似的行为,那么你应该创建一个返回方法返回值的属性,然后从实例中获取该属性。