在python

时间:2018-02-13 08:53:24

标签: python for-loop split nested

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

inputString

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

2 个答案:

答案 0 :(得分: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())

答案 1 :(得分:0)

下面是一些示例代码我演示了一个类似于你正在寻找的“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