我最近在我们的代码中遇到了很多类似这样的地方
...
globals()['machine'] = otherlib.Machine()
globals()['logger'] = otherlib.getLogger()
globals()['logfile'] = datetime.datetime.now().strftim('logfiles_%Y_%m_%d.log')
我对人们为什么会这样做而不是这样做感到困惑
global machine
machine = otherlib.Machine()
等等。
这是一个稍微匿名的功能,可以完全完成此操作:
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)
它也使pylint(0.25)引起了我的困扰。
有什么理由要这样编码吗?我们的代码中对eval的使用最少,而库中没有
PS我检查了Reason for globals() in python,但它并没有真正回答您为什么要使用它在程序中设置全局变量
最佳答案
也许函数使用与全局变量同名的局部变量,而程序员不想费心更改变量名吗?
def foo(bar):
global bar # SyntaxError
bar = bar + 1
def foo(bar):
globals()['bar'] = bar + 1
foo(1)
print(bar) # prints 2
另一个用例是动态定义变量名,尽管仍然有些变化(显然您给出的示例函数中不是这种情况)。这很少是一个好主意,但是至少在此站点上确实存在很多问题。例如:
>>> 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
否则,我只能想到这样做的一个原因:也许某个监督实体要求以这种方式设置所有全局变量,例如“为了使它变得非常非常清楚,这些变量是全局的”。或者,可能是同一监督实体全面禁止
global
关键字,或者停靠了程序员为每一行付费。我并不是说这些都是很好的理由,但是话又说回来,如果不是出于范围界定的目的,我真的无法想到以这种方式定义变量的充分理由(即使那样,这似乎也是有问题的... )。
为了以防万一,我进行了时间检查,以查看
globals()
调用是否比使用关键字更快。我希望函数调用+字典访问会明显变慢,而且确实如此。>>> import timeit
>>> timeit.timeit('foo()', 'def foo():\n\tglobals()["bar"] = 1',number=10000000)
2.733132876863408
>>> timeit.timeit('foo()', 'def foo():\n\tglobal bar\n\tbar = 1',number=10000000)
1.6613818077011615
鉴于您发布的代码和我的计时结果,我可以认为没有正当理由,因为您正在寻找要像这样编写的代码。看起来是误导的管理要求或简单的无能。