Why would people use globals() to define variables
我最近在我们的代码中遇到了很多这样的地方
1 2 3 4 | ... globals()['machine'] = otherlib.Machine() globals()['logger'] = otherlib.getLogger() globals()['logfile'] = datetime.datetime.now().strftim('logfiles_%Y_%m_%d.log') |
我不明白为什么人们会这样做,而不是这样做
1 2 | global machine machine = otherlib.Machine() |
号
等等。
这里有一个稍微匿名的功能,它可以完全做到这一点:
1 2 3 4 5 6 7 8 9 10 11 | def openlog(num) log_file = '/log_dir/thisprogram.' + num if os.path.exists(log_file): os.rename(log_file, log_file + '.old') try: globals()["log"] = open(log_file, 'w') return log except: print 'Unable to open ' + log_file sys.exit(1) |
它混淆了皮林特(0.25)和我的地狱。
有什么理由用这种方式编码吗?在我们的代码中,eval的用法是最少的,而这不在库中
ps我在python中检查了globals()的原因,但它并没有真正回答为什么要用它来设置程序中的globals。
也许函数使用了与全局变量同名的局部变量,而程序员不想更改变量名?
1 2 3 | def foo(bar): global bar # SyntaxError bar = bar + 1 |
1 2 3 4 | def foo(bar): globals()['bar'] = bar + 1 foo(1) print(bar) # prints 2 |
号
另一个用例是动态定义变量名,尽管仍然有点似是而非(显然不是您给出的示例函数中的情况)。这很少是一个好主意,如果有的话,但至少在这个网站上有很多问题。例如:
1 2 3 4 5 6 7 8 9 10 | >>> def new_variable(): ... name = input("Give your new variable a name!") ... value = input("Give your new variable a value!") ... globals()[name] = value ... >>> new_variable() Give your new variable a name! foo Give your new variable a value! bar >>> print(foo) bar |
否则,我只能想到一个原因:也许一些监督实体要求所有全局变量都以这种方式设置,例如,"为了真正清楚地表明这些变量是全局的"。或者同一个监督实体已经全面禁止了
我并不是说这其中任何一个都是一个好的理由,但是再一次地,我真的不能想象一个好的理由来定义变量,如果不是为了范围界定的目的(即使那样,这似乎是有问题的…)。
为了以防万一,我做了一个定时检查,看看
1 2 3 4 5 6 7 8 | >>> import timeit >>> timeit.timeit('foo()', 'def foo(): \tglobals()["bar"] = 1',number=10000000) 2.733132876863408 >>> timeit.timeit('foo()', 'def foo(): \tglobal bar \tbar = 1',number=10000000) 1.6613818077011615 |
。
考虑到您发布的代码和我的计时结果,我想不出任何合理的理由来让您希望这样编写代码。看起来要么管理要求有误,要么就是单纯的无能。
作者是PHP转换者吗?这是PHP中的有效代码:
1 | $GLOBALS['b'] = $GLOBALS['a'] + $GLOBALS['b']; |
请参阅此了解更多示例。如果有人习惯了这种编写代码的方式,也许他们只是使用了与之最接近的Python匹配的方式,而不需要检查其他方法。
有时,您会使用一个超全局的