【问题标题】:Set a nested object property from a dot notation string in python从python中的点表示法字符串设置嵌套对象属性
【发布时间】:2018-02-13 08:53:23
【问题描述】:

我正在编写一个函数,它接收一个父对象data 和一个字符串inputString,它可能包含也可能不包含点表示法来表示嵌套对象(即'nestedObject.itemA)。该函数应将datainputString 属性设置为随机字符串。如果字符串inputString 是嵌套对象,则函数应将嵌套对象的值设置为随机字符串。我不知道如何在 for 循环中处理这一切。我想做这样的事情:

split_objects = value.split(“.”)
for item in split_objects:
    data.__setattr__(item, get_random_string())

但是,在嵌套对象的情况下,上面会将嵌套对象设置为随机字符串,而不是内部的字段。有人可以帮助我处理这两种情况的语法吗?在此先感谢...

【问题讨论】:

    标签: python for-loop split nested


    【解决方案1】:

    您需要先获得对data.nestedObject 的引用,然后才能使用setattr 更改data.nestedObject.itemA

    prefix, suffix = value.rsplit(".",1)
    # now prefix is nestedOjbect and suffix is itemA
    ref = getattr(data,prefix)
    setattr(ref,suffix,get_random_string())
    

    您需要获得与inputString 中的点一样多的参考。所以,如果你在data中有任意深度嵌套的结构

    value = "nestedObject.nestedObject2.nestedObject3.itemA"
    path, attribute = value.rsplit(".",1)
    path = path.split(".")
    ref = data
    while path:
        element, path = path[0], path[1:]
        ref = getattr(ref, element)
    setattr(ref, attribute, get_random_string())
    

    【讨论】:

      【解决方案2】:

      这是一些示例代码,用于演示我编写的“setField”函数,类似于您正在寻找的内容:

      def setField(obj, fieldPath, value):
          fields = fieldPath.split(".")
          cur = obj
          # use all but the last field to traverse the objects
          for field in fields[:-1]:
              cur = getattr(cur, field)
          # use the last field as the property within the object to be overwritten (not traversed)
          setattr(cur, fields[-1], value)
      
      # USE CASE EXAMPLE:
      
      class PrintBase:
          def dump(self, level=0):
              for key, value in vars(self).iteritems():
                  print " "*(level*4) + key + ":", value
                  if isinstance(value, PrintBase):
                      value.dump(level+1)
      
      class BottomObject(PrintBase):
          def __init__(self):
              self.fieldZ = 'bottomX'
      
      class MiddleObject(PrintBase):
          def __init__(self):
              self.fieldX = 'middleQ'
              self.fieldY = BottomObject()
      
      class TopObject(PrintBase):
          def __init__(self):
              self.fieldA = 'topA'
              self.fieldB = MiddleObject()
      
      top_obj = TopObject()
      print "=== BEFORE ==="
      top_obj.dump()
      print "=== AFTER ==="
      setField(top_obj, 'fieldB.fieldY.fieldZ', '!!!! test value !!!!')
      top_obj.dump()
      

      这是示例输出:

      === BEFORE ===
      fieldB: <__main__.MiddleObject instance at 0x7f5eb1cc6b48>
          fieldX: middleQ
          fieldY: <__main__.BottomObject instance at 0x7f5eb1cc6b90>
              fieldZ: bottomX
      fieldA: topA
      === AFTER ===
      fieldB: <__main__.MiddleObject instance at 0x7f5eb1cc6b48>
          fieldX: middleQ
          fieldY: <__main__.BottomObject instance at 0x7f5eb1cc6b90>
              fieldZ: !!!! test value !!!!
      fieldA: topA
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-04-11
        • 1970-01-01
        • 2019-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-28
        相关资源
        最近更新 更多