从作用域中的变量创建dict
dictvars的Python项目详细描述
字典
从作用域中的变量创建dict。在
为什么?在
在python中,从变量创建dict是非常常见的 定义的,例如从视图函数返回上下文dict时 将传递给序列化程序或模板呈现。在
代码如下:
returndict(user=user,form=form,comments=comments)
使用varsdict
可以消除所有
在代码中命名了两次的变量。在
上述代码可替换为:
^{pr2}$或者,变量名可以用varsnamed
作为字符串传递:
returnvarsnamed('form','comments','myapp')
安装
pip install dictvars
示例
全局变量也可以传递给varsdict
。在
下面的示例是一个完整的代码来说明如何
一个“真正的”代码看起来就像使用和不使用varsdict
和varsnamed
。在
fromdictvarsimportdictvars,varsnamedmyapp='MyApp'# a global vardefsomefunc_regular_python():# pretend this is a controller code that makes senseuser=dict(some='very',complex_='expression')permission=user.get('permission',False)user_has_permission=bool(permission)form=dict(another='object',perm=user_has_permission)comments=[]forvaluesin[d.values()fordin[user,form]]:comments.extend([vforvinvaluesifisinstance(v,str)])returndict(form=form,comments=comments,myapp=myapp)defsomefunc_dictvars():# pretend this is a controller code that makes senseuser=dict(some='very',complex_='expression')permission=user.get('permission',False)user_has_permission=bool(permission)form=dict(another='object',perm=user_has_permission)comments=[]forvaluesin[d.values()fordin[user,form]]:comments.extend([vforvinvaluesifisinstance(v,str)])returndictvars(form,comments,myapp)defsomefunc_varsnamed():# pretend this is a controller code that makes senseuser=dict(some='very',complex_='expression')permission=user.get('permission',False)user_has_permission=bool(permission)form=dict(another='object',perm=user_has_permission)comments=[]forvaluesin[d.values()fordin[user,form]]:comments.extend([vforvinvaluesifisinstance(v,str)])returnvarsnamed('form','comments','myapp')if__name__=='__main__':frompprintimportpprintpprint(somefunc_regular_python())pprint(somefunc_dictvars())pprint(somefunc_varsnamed())
所有版本的输出都相同:
{'comments': ['very', 'expression', 'object'],
'form': {'another': 'object', 'perm': False},
'myapp': 'MyApp'}
{'comments': ['very', 'expression', 'object'],
'form': {'another': 'object', 'perm': False},
'myapp': 'MyApp'}
{'comments': ['very', 'expression', 'object'],
'form': {'another': 'object', 'perm': False},
'myapp': 'MyApp'}
重命名变量
dict
的标准kwargs语法也受dictvars
的支持。在
假设您有一个变量current_user
,但是您只想使用user
根据你的口述:
defsomefunc_dictvars(current_user):form=dict(some='very',complex_='expression')comments=['bla','bla']returndictvars(form,comments,app=myapp,user=current_user)
按预期工作:
{'app': 'MyApp',
'comments': ['bla', 'bla'],
'form': {'some': 'very', 'complex_': 'expression'},
'user': 'John Do'}
局限性
为了从传递的变量中创建dict,需要对 获取原始变量名:作用域中的变量列表 遍历查找相同的变量(相同的引用, 相同的id)。在
此实现细节可能会导致意外的变量泄漏 当一个对象被多次引用时。在
例如:
defsomefunc():a='1'b='2'c='3'leak=breturndictvars(a,b)print(somefunc())
退货:
{'a': '1',
'b': '2',
'leak': '2'}
请注意,没有新的值或对象被泄露,只有 已经在dict中的对象
我发现这种情况很少见,大多数时候都不是问题, 返回的其他变量通常可以忽略。在
我还不知道怎么解决这个问题。乐于接受建议。在
如果这是特定上下文中的问题,可以通过 具有显式名称的违规变量,就像常规dict:
defsomefunc():a='1'b='2'c='3'no_leaks_now=breturndictvars(a,b=b)print(somefunc())
退货:
{'a': '1',
'b': '2'}
在这种情况下,另一种选择是用dictvars
来交换
^{cd2}:
returnvarsnamed('a','b')
- 项目
标签: