<small id='pSYcs'></small><noframes id='pSYcs'>

    1. <i id='pSYcs'><tr id='pSYcs'><dt id='pSYcs'><q id='pSYcs'><span id='pSYcs'><b id='pSYcs'><form id='pSYcs'><ins id='pSYcs'></ins><ul id='pSYcs'></ul><sub id='pSYcs'></sub></form><legend id='pSYcs'></legend><bdo id='pSYcs'><pre id='pSYcs'><center id='pSYcs'></center></pre></bdo></b><th id='pSYcs'></th></span></q></dt></tr></i><div id='pSYcs'><tfoot id='pSYcs'></tfoot><dl id='pSYcs'><fieldset id='pSYcs'></fieldset></dl></div>
    2. <tfoot id='pSYcs'></tfoot>
      • <bdo id='pSYcs'></bdo><ul id='pSYcs'></ul>

    3. <legend id='pSYcs'><style id='pSYcs'><dir id='pSYcs'><q id='pSYcs'></q></dir></style></legend>
    4. 嵌套子对象/链式属性上的 getattr 和 setattr?

      时间:2023-09-13
      <legend id='vu1B8'><style id='vu1B8'><dir id='vu1B8'><q id='vu1B8'></q></dir></style></legend><tfoot id='vu1B8'></tfoot>
        • <bdo id='vu1B8'></bdo><ul id='vu1B8'></ul>

          <i id='vu1B8'><tr id='vu1B8'><dt id='vu1B8'><q id='vu1B8'><span id='vu1B8'><b id='vu1B8'><form id='vu1B8'><ins id='vu1B8'></ins><ul id='vu1B8'></ul><sub id='vu1B8'></sub></form><legend id='vu1B8'></legend><bdo id='vu1B8'><pre id='vu1B8'><center id='vu1B8'></center></pre></bdo></b><th id='vu1B8'></th></span></q></dt></tr></i><div id='vu1B8'><tfoot id='vu1B8'></tfoot><dl id='vu1B8'><fieldset id='vu1B8'></fieldset></dl></div>
              <tbody id='vu1B8'></tbody>

            <small id='vu1B8'></small><noframes id='vu1B8'>

              1. 本文介绍了嵌套子对象/链式属性上的 getattr 和 setattr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                问题描述

                我有一个对象 (Person),它有多个子对象 (Pet, Residence) 作为属性.我希望能够像这样动态设置这些子对象的属性:

                I have an object (Person) that has multiple subobjects (Pet, Residence) as properties. I want to be able to dynamically set the properties of these subobjects like so:

                class Person(object):
                    def __init__(self):
                        self.pet = Pet()
                        self.residence = Residence()
                
                class Pet(object):
                    def __init__(self,name='Fido',species='Dog'):
                        self.name = name
                        self.species = species
                
                class Residence(object):
                    def __init__(self,type='House',sqft=None):
                        self.type = type
                        self.sqft=sqft
                
                
                if __name__=='__main__':
                    p=Person()
                    setattr(p,'pet.name','Sparky')
                    setattr(p,'residence.type','Apartment')
                    print p.__dict__
                

                目前我得到了错误的输出:{'pet': <__main__.Pet object at 0x10c5ec050>, 'residence': <__main__.Residence object at 0x10c5ec0d0>, 'pet.name': 'Sparky', 'residence.type': '公寓'}

                Currently I get the wrong output: {'pet': <__main__.Pet object at 0x10c5ec050>, 'residence': <__main__.Residence object at 0x10c5ec0d0>, 'pet.name': 'Sparky', 'residence.type': 'Apartment'}

                如您所见,不是在 PersonPet 子对象上设置 name 属性,而是一个新属性 pet.name 是在 Person 上创建的.

                As you can see, instead of setting the name attribute on the Pet subobject of the Person, a new attribute pet.name is created on the Person.

                • 我无法将person.pet指定为setattr(),因为不同的子对象会被同一个方法设置,解析一些文本并填写如果/当找到相关键时,对象属性.

                • I cannot specify person.pet to setattr() because different sub-objects will be set by the same method, which parses some text and fills in the object attributes if/when a relevant key is found.

                有没有一种简单/内置的方法来完成这个?

                Is there a easy/builtin way to accomplish this?

                或者也许我需要编写一个递归函数来解析字符串并多次调用 getattr() 直到找到必要的子对象然后调用 setattr()?

                Or perhaps I need to write a recursive function to parse the string and call getattr() multiple times until the necessary subobject is found and then call setattr() on that found subobject?

                推荐答案

                你可以使用 functools.reduce:

                You could use functools.reduce:

                import functools
                
                def rsetattr(obj, attr, val):
                    pre, _, post = attr.rpartition('.')
                    return setattr(rgetattr(obj, pre) if pre else obj, post, val)
                
                # using wonder's beautiful simplification: https://stackoverflow.com/questions/31174295/getattr-and-setattr-on-nested-objects/31174427?noredirect=1#comment86638618_31174427
                
                def rgetattr(obj, attr, *args):
                    def _getattr(obj, attr):
                        return getattr(obj, attr, *args)
                    return functools.reduce(_getattr, [obj] + attr.split('.'))
                

                rgetattrrsetattrgetattrsetattr 的直接替换,它还可以处理带点的 attr 字符串.

                rgetattr and rsetattr are drop-in replacements for getattr and setattr, which can also handle dotted attr strings.

                import functools
                
                class Person(object):
                    def __init__(self):
                        self.pet = Pet()
                        self.residence = Residence()
                
                class Pet(object):
                    def __init__(self,name='Fido',species='Dog'):
                        self.name = name
                        self.species = species
                
                class Residence(object):
                    def __init__(self,type='House',sqft=None):
                        self.type = type
                        self.sqft=sqft
                
                def rsetattr(obj, attr, val):
                    pre, _, post = attr.rpartition('.')
                    return setattr(rgetattr(obj, pre) if pre else obj, post, val)
                
                def rgetattr(obj, attr, *args):
                    def _getattr(obj, attr):
                        return getattr(obj, attr, *args)
                    return functools.reduce(_getattr, [obj] + attr.split('.'))
                

                <小时>

                if __name__=='__main__':
                    p = Person()
                    print(rgetattr(p, 'pet.favorite.color', 'calico'))
                    # 'calico'
                
                    try:
                        # Without a default argument, `rgetattr`, like `getattr`, raises
                        # AttributeError when the dotted attribute is missing
                        print(rgetattr(p, 'pet.favorite.color'))
                    except AttributeError as err:
                        print(err)
                        # 'Pet' object has no attribute 'favorite'
                
                    rsetattr(p, 'pet.name', 'Sparky')
                    rsetattr(p, 'residence.type', 'Apartment')
                    print(p.__dict__)
                    print(p.pet.name)
                    # Sparky
                    print(p.residence.type)
                    # Apartment
                

                这篇关于嵌套子对象/链式属性上的 getattr 和 setattr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                <tfoot id='Cobiz'></tfoot>
                • <bdo id='Cobiz'></bdo><ul id='Cobiz'></ul>

                  <legend id='Cobiz'><style id='Cobiz'><dir id='Cobiz'><q id='Cobiz'></q></dir></style></legend>

                      <small id='Cobiz'></small><noframes id='Cobiz'>

                      1. <i id='Cobiz'><tr id='Cobiz'><dt id='Cobiz'><q id='Cobiz'><span id='Cobiz'><b id='Cobiz'><form id='Cobiz'><ins id='Cobiz'></ins><ul id='Cobiz'></ul><sub id='Cobiz'></sub></form><legend id='Cobiz'></legend><bdo id='Cobiz'><pre id='Cobiz'><center id='Cobiz'></center></pre></bdo></b><th id='Cobiz'></th></span></q></dt></tr></i><div id='Cobiz'><tfoot id='Cobiz'></tfoot><dl id='Cobiz'><fieldset id='Cobiz'></fieldset></dl></div>