我正在编写一个函数,它接受一个父对象data
和一个字符串inputString
,它可能包含或不包含点符号来表示嵌套对象(即'nestedObject.itemA)。该函数应将inputString
的{{1}}属性设置为随机字符串。如果字符串data
是嵌套对象,则该函数应将嵌套对象的值设置为随机字符串。我无法弄清楚如何在for循环中处理这一切。我想做这样的事情:
inputString
但是,在嵌套对象的情况下,上面会将嵌套对象设置为随机字符串,而不是内部字段。有人能够帮助我处理这两种情况的语法吗?提前谢谢......
答案 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