在属性和方法上使用attrgetter与methodcaller进行排序时的异步行为

时间:2015-03-22 02:17:18

标签: python python-2.7 sorting

想象一下,我的课程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根据foogetbar的值对它们进行排序。

 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

1 个答案:

答案 0 :(得分:1)

  

使用methodcaller进行排序会在传递属性时引发错误...,那么为什么attrgetter在收到方法时不会引发错误?

因为在Python中,实例方法属性。唯一的区别是返回的值是一个绑定方法,通常称之为。

如果你想要两者都有类似的行为,那么你应该创建一个返回方法返回值的属性,然后从实例中获取该属性。