2024-04-27 02:58:25 发布
网友
class A(): pass a = A() b = A() a.b = b b.c = 1 a.b # this is b getattr(a, "b") # so is this a.b.c # this is 1 getattr(a, "b.c") # this raises an AttributeError
对我来说,假设是后者似乎很自然。我相信这是有原因的。它是什么?
我认为您的困惑源于这样一个事实:直点表示法(exa.b.c)访问的参数与getattr()相同,但解析逻辑不同。虽然它们本质上都是对象的__dict__属性的键,但是getattr()并没有绑定到对点可访问属性更严格的要求。例如
a.b.c
getattr()
__dict__
setattr(foo, 'Big fat ugly string. But you can hash it.', 2)
是有效的,因为该字符串只是成为foo.__dict__中的哈希键,但是
foo.__dict__
foo.Big fat ugly string. But you can hash it. = 2
以及
foo.'Big fat ugly string. But you can hash it.' = 2
是语法错误,因为现在您要求解释器将这些内容解析为原始代码,但这不起作用。
另一方面,当foo.b.c等同于foo.__dict__['b'].__dict__['c']时,getattr(foo, 'b.c')等同于foo.__dict__['b.c']。这就是为什么getattr不能像您期望的那样工作。
foo.b.c
foo.__dict__['b'].__dict__['c']
getattr(foo, 'b.c')
foo.__dict__['b.c']
getattr
Python's built-in ^{} function启用您要查找的功能。下面是一个简单的小助手函数,它可以完成任务:
class NoDefaultProvided(object): pass def getattrd(obj, name, default=NoDefaultProvided): """ Same as getattr(), but allows dot notation lookup Discussed in: http://stackoverflow.com/questions/11975781 """ try: return reduce(getattr, name.split("."), obj) except AttributeError, e: if default != NoDefaultProvided: return default raise
试验证明
>>> getattrd(int, 'a') AttributeError: type object 'int' has no attribute 'a' >>> getattr(int, 'a') AttributeError: type object 'int' has no attribute 'a' >>> getattrd(int, 'a', None) None >>> getattr(int, 'a', None) None >>> getattrd(int, 'a', None) None >>> getattrd(int, '__class__.__name__') type >>> getattrd(int, '__class__') <type 'type'>
不能在getattr函数中放置句点,因为getattr类似于访问对象的字典查找(但由于子类化和其他Python实现细节,比这个复杂一点)。
如果在上使用“dir”函数,将看到与对象属性对应的字典键。在本例中,字符串“b.c”不在字典键集中。
对getattr执行此操作的唯一方法是嵌套调用:
getattr(getattr(a, "b"), "c")
幸运的是,标准库有更好的解决方案!
import operator operator.attrgetter("b.c")(a)
我认为您的困惑源于这样一个事实:直点表示法(ex
a.b.c
)访问的参数与getattr()
相同,但解析逻辑不同。虽然它们本质上都是对象的__dict__
属性的键,但是getattr()
并没有绑定到对点可访问属性更严格的要求。例如是有效的,因为该字符串只是成为
foo.__dict__
中的哈希键,但是以及
是语法错误,因为现在您要求解释器将这些内容解析为原始代码,但这不起作用。
另一方面,当
foo.b.c
等同于foo.__dict__['b'].__dict__['c']
时,getattr(foo, 'b.c')
等同于foo.__dict__['b.c']
。这就是为什么getattr
不能像您期望的那样工作。Python's built-in ^{} function 启用您要查找的功能。下面是一个简单的小助手函数,它可以完成任务:
试验证明
不能在getattr函数中放置句点,因为getattr类似于访问对象的字典查找(但由于子类化和其他Python实现细节,比这个复杂一点)。
如果在上使用“dir”函数,将看到与对象属性对应的字典键。在本例中,字符串“b.c”不在字典键集中。
对
getattr
执行此操作的唯一方法是嵌套调用:幸运的是,标准库有更好的解决方案!
相关问题 更多 >
编程相关推荐