我想映射一个属性,所以我尝试了
map(lambda o: cls.prop(o), list_of_objects)
该属性在外部库中定义为:
@property
def prop(self):
但是,我收到TypeError
错误。
我对它进行了测试"未映射",cls.prop(an_object)
工作得很好,应该是等同于an_object.prop
。
我做错了什么?我怎么能做到这一点?
(我知道列表理解[o.prop for o in list_of_objects]
,但我想学习并理解上面出了什么问题。)
答案 0 :(得分:9)
A property, accessed on the class, returns the property
object itself, and not the wrapped function. A property wraps three functions, the getter, setter and deleter (each of these can be None
):
>>> class Foo(object):
... @property
... def prop(self):
... return 'bar'
...
>>> Foo.prop
<property object at 0x107102bd8>
>>> Foo.prop.fget, Foo.prop.fset, Foo.prop.fdel
(<function Foo.prop at 0x1073366a8>, None, None)
You need to access the fget
attribute to get just the getter:
map(lambda o: cls.prop.fget(o), list_of_objects)
However, this is overkill, just access the attribute directly:
map(lambda o: o.prop, list_of_objects)
or use a operator.attrgetter()
object:
from operator import attrgetter
map(attrgetter('prop'), list_of_objects)
The latter has the advantage that the map()
C loop won't have to step back into the Python interpreter loop to execute the lambda
bytecode, attrgetter()
can do it's job entirely in C making the combination faster.