是否有一个库可以遵循一系列索引和 getattr 操作?
Is there a library to follow a sequence of indexing and `getattr` operations?
我有一堆对象,它们有成员,它们的成员有成员,...,我需要在某个地方做索引,然后访问成员...
所以,基本上,我想得到 obj.member1.member2[3].member4
并且我还想分配 obj.member1[2].member3.member4 = new_value
。我想生成这些 "paths" 来描述何时使用 getattr
以及何时动态使用索引。有图书馆吗?我想象界面像
get_obj_path(obj, (("member1", "a"), ("member2", "a"), (3, "i"), ("member4", "a")))
和
assign_obj_path(obj, (("member1", "a"), (2, "i"), ("member3", "a"), ("member4", "a")), new_value)
您可以自己实现这些功能:
def get_obj_path(obj, path):
if not path:
return obj
(key, kind), *path = path
if kind == "a":
obj = getattr(obj, key)
elif kind == "i":
obj = obj[key]
else:
raise ValueError(f"invalid kind '{kind}'.")
return get_obj_path(obj, path)
def assign_obj_path(obj, path, value):
(key, kind), *path = path
if not path:
if kind == "a":
setattr(obj, key, value)
elif kind == "i":
obj[key] = value
else:
raise ValueError(f"invalid kind '{kind}'.")
else:
if kind == "a":
obj = getattr(obj, key)
elif kind == "i":
obj = obj[key]
else:
raise ValueError(f"invalid kind '{kind}'.")
assign_obj_path(obj, path, value)
# Test
class MyClass: pass
obj1 = MyClass()
obj1.i = 1
obj2 = MyClass()
obj2.lst = [obj1]
assign_obj_path(obj2, (("lst", "a"), (0, "i"), ("i", "a")), 2)
print(get_obj_path(obj2, (("lst", "a"), (0, "i"), ("i", "a"))))
# 2
我有一堆对象,它们有成员,它们的成员有成员,...,我需要在某个地方做索引,然后访问成员...
所以,基本上,我想得到 obj.member1.member2[3].member4
并且我还想分配 obj.member1[2].member3.member4 = new_value
。我想生成这些 "paths" 来描述何时使用 getattr
以及何时动态使用索引。有图书馆吗?我想象界面像
get_obj_path(obj, (("member1", "a"), ("member2", "a"), (3, "i"), ("member4", "a")))
和
assign_obj_path(obj, (("member1", "a"), (2, "i"), ("member3", "a"), ("member4", "a")), new_value)
您可以自己实现这些功能:
def get_obj_path(obj, path):
if not path:
return obj
(key, kind), *path = path
if kind == "a":
obj = getattr(obj, key)
elif kind == "i":
obj = obj[key]
else:
raise ValueError(f"invalid kind '{kind}'.")
return get_obj_path(obj, path)
def assign_obj_path(obj, path, value):
(key, kind), *path = path
if not path:
if kind == "a":
setattr(obj, key, value)
elif kind == "i":
obj[key] = value
else:
raise ValueError(f"invalid kind '{kind}'.")
else:
if kind == "a":
obj = getattr(obj, key)
elif kind == "i":
obj = obj[key]
else:
raise ValueError(f"invalid kind '{kind}'.")
assign_obj_path(obj, path, value)
# Test
class MyClass: pass
obj1 = MyClass()
obj1.i = 1
obj2 = MyClass()
obj2.lst = [obj1]
assign_obj_path(obj2, (("lst", "a"), (0, "i"), ("i", "a")), 2)
print(get_obj_path(obj2, (("lst", "a"), (0, "i"), ("i", "a"))))
# 2