大量操作 dict 内元素时有什么能省略 dict 名字的语法糖?

查看 94|回复 6
作者:xuegy   
标题可能描述的不够具体。大致操作是从 json 读入数据,经过一通计算,用 python-docx-replace 替换模版快速生成文档。代码举例(省略数字格式化字符串部分):
dict = json.load(xxx)
dict[A]=dict[B]+dict[C]
dict[D]=dict[E]-dict[F]
dict[G]=dict[H]*dict[I]
dict[J]=dict[K]/dict[L]
...
docx_replace(doc, **dict)
因为实际代码是很长的数学公式,个人觉得写这么多dict[]可读性实在太差,于是采用了如下写法(我知道不妥,但是想不出更好的),被 LD 批评很不 Pythonic 。
dict = json.load(xxx)
locals().update(dict)
A=B+C
D=E-F
G=H*I
J=K/L
...
dict.update({key: value for (key, value) in locals().items() if type(value) == int or type(value) == float})
docx_replace(doc, **dict)
求助各位高人有没有更合理的写法?

dict, value, JSON, locals

thinkershare   
没有办法,python 不支持这种类似 js 的 with 临时作用域附加(js 的 with 大多数时候也被认为是一个不好的东西),因为 python 字典的 key 很可能不是一个合法的变量名称,而且它的类型也不一定是一个字符串。
不管使用 local()或者 global 都是一个糟糕的实现方式。
xuegy
OP
  
@thinkershare 有个前提是,我的 json 文件可以保证所有的 key 都是合法的变量名称
hitmanx   
想到一个更 hack 的方法,把计算放到一个 function 里,定义一个类似 C/C++里面"preprocess"的 decorator 加在函数上。
在这个 decorator 的实现:通过 inspect.getsource(func)去拿到 source 。然后每一行里把 dict 里的存在的 token 替换成 dict[token],最后调用 exec()去执行替换完的字符串。
相当于你自己实现了一个 preprocessor
Ricardoo   
这种我一般会转成类
my_json = type('MyJson', (object,), my_json)
my_json.A = my_json.B + my_json.C
只比 dict 方式强一丢丢
thinkershare   
@xuegy 没有办法,因为变量在现代编程语言中都是很特殊的存在。任何尝试动态解构变量的做法都会导致性能的下降,因为编译器会尝试在今日函数前对函数做优化。确定要给整个函数分配的堆栈空间大小,如果搞动态变量注入到局部,那么函数将无法优化,函数的机器码也无法被缓存重用,这些都是实实在在的性能问题。javascript 当初对 with 的支持就是一个错误。python 已经有很多语法都是因为容易写但性能差而被滥用了,你看看现在 python 写的很多程序的性能为什么如此差就明白了,python 现在支持的语法已经非常容易让人写出性能极差,时间复杂度极高的代码了。可读性和性能有时候就是相互矛盾的。
我们目前一般是这么做的 d=EasyDict(json.load(txt), d.a+d.b 这样。
stein42   
exec 函数了解一下
```
env = {'a': 1, 'b': 2}
exec('c = a + b', None, env)
print(env)
```
您需要登录后才可以回帖 登录 | 立即注册

返回顶部