Why does `getattr` not support consecutive attribute retrievals?

后端 未结 7 1422
梦如初夏
梦如初夏 2021-02-01 01:53
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 Attrib         


        
7条回答
  •  误落风尘
    2021-02-01 02:29

    I think your confusion arises from the fact that straight dot notation (ex a.b.c) accesses the same parameters as getattr(), but the parsing logic is different. While they both essentially key in to an object's __dict__ attribute, getattr() is not bound to the more stringent requirements on dot-accessible attributes. For instance

    setattr(foo, 'Big fat ugly string.  But you can hash it.', 2)
    

    Is valid, since that string just becomes a hash key in foo.__dict__, but

    foo.Big fat ugly string.  But you can hash it. = 2
    

    and

    foo.'Big fat ugly string.  But you can hash it.' = 2
    

    are syntax errors because now you are asking the interpreter to parse these things as raw code, and that doesn't work.

    The flip side of this is that while foo.b.c is equivalent to foo.__dict__['b'].__dict__['c'], getattr(foo, 'b.c') is equivalent to foo.__dict__['b.c']. That's why getattr doesn't work as you are expecting.

提交回复
热议问题