要从字面上得到你想要的东西,你必须摆弄文件的语法树。我不认为这样做是可取的,但我无法抗拒尝试的诱惑。所以我们开始吧。
首先,我们创建一个具有my_execfile()
类似内置函数的模块execfile()
,除了所有出现的字典显示,例如{3: 4, "a": 2}
由对dict()
构造函数的显式调用替换,例如dict([(3, 4), ('a', 2)])
。(当然我们可以通过调用来直接替换它们collections.OrderedDict()
,但我们不想太打扰。)下面是代码:
import ast
class DictDisplayTransformer(ast.NodeTransformer):
def visit_Dict(self, node):
self.generic_visit(node)
list_node = ast.List(
[ast.copy_location(ast.Tuple(list(x), ast.Load()), x[0])
for x in zip(node.keys, node.values)],
ast.Load())
name_node = ast.Name("dict", ast.Load())
new_node = ast.Call(ast.copy_location(name_node, node),
[ast.copy_location(list_node, node)],
[], None, None)
return ast.copy_location(new_node, node)
def my_execfile(filename, globals=None, locals=None):
if globals is None:
globals = {}
if locals is None:
locals = globals
node = ast.parse(open(filename).read())
transformed = DictDisplayTransformer().visit(node)
exec compile(transformed, filename, "exec") in globals, locals
有了这个修改,我们可以通过覆盖来修改字典显示的行为dict
。这是一个例子:
# test.py
from collections import OrderedDict
print {3: 4, "a": 2}
dict = OrderedDict
print {3: 4, "a": 2}
现在我们可以使用 运行这个文件my_execfile("test.py")
,产生输出
{'a': 2, 3: 4}
OrderedDict([(3, 4), ('a', 2)])
请注意,为简单起见,上述代码不涉及字典推导,应将其转换为传递给dict()
构造函数的生成器表达式。您需要向该类添加一个visit_DictComp()
方法。DictDisplayTransformer
鉴于上面的示例代码,这应该是直截了当的。
同样,我不推荐这种语言语义的混乱。你看过这个ConfigParser
模块吗?