一种getattr和setattr,用于嵌套对象、列表、dict及其任何组合,而不诉诸eval
magicattr的Python项目详细描述
magicattr
一个getattr和setattr,用于嵌套对象、列表, 字典,以及不使用eval的任何组合。
它与getattr和setattr的不同之处在于它保留了故障原因 而不是总是提出一个属性错误。
示例
假设我们有一个Person类,如下所示:
classPerson:settings={'autosave':True,'style':{'height':30,'width':200},'themes':['light','dark']}def__init__(self,name,age,friends):self.name=nameself.age=ageself.friends=friendsbob=Person(name="Bob",age=31,friends=[])jill=Person(name="Jill",age=29,friends=[bob])jack=Person(name="Jack",age=28,friends=[bob,jill])
有了magicattr,我们可以做到这一点
# Nothing newassertmagicattr.get(bob,'age')==31# Listsassertmagicattr.get(jill,'friends[0].name')=='Bob'assertmagicattr.get(jack,'friends[-1].age')==29# Dict lookupsassertmagicattr.get(jack,'settings["style"]["width"]')==200# Combination of lookupsassertmagicattr.get(jack,'settings["themes"][-2]')=='light'assertmagicattr.get(jack,'friends[-1].settings["themes"][1]')=='dark'# Setattrmagicattr.set(bob,'settings["style"]["width"]',400)assertmagicattr.get(bob,'settings["style"]["width"]')==400# Nested objectsmagicattr.set(bob,'friends',[jack,jill])assertmagicattr.get(jack,'friends[0].friends[0]')==jackmagicattr.set(jill,'friends[0].age',32)assertbob.age==32
你也可以这样删除。
# Deletionmagicattr.delete(jill,'friends[0]')assertlen(jill.friends)==0magicattr.delete(jill,'age')assertnothasattr(jill,'age')magicattr.delete(bob,'friends[0].age')assertnothasattr(jack,'age')
如果有人想惹你怎么办?
# Unsupportedwithpytest.raises(NotImplementedError)ase:magicattr.get(bob,'friends[0+1]')withpytest.raises(SyntaxError)ase:magicattr.get(bob,'friends[')withpytest.raises(ValueError)ase:magicattr.get(bob,'friends = [1,1]')# Nice try, function calls are not allowedwithpytest.raises(ValueError):magicattr.get(bob,'friends.pop(0)')
我错过什么了吗?告诉我!
它不能做什么?切片、表达式、函数调用、从列表中追加/弹出、求值等…
它是如何工作的?将attr字符串解析为ast节点并手动对其求值。
安装
pip install magicattr
许可证
麻省理工学院
希望有帮助,干杯!