我最近在我们的代码中遇到了很多类似这样的地方

...
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

鉴于您发布的代码和我的计时结果,我可以认为没有正当理由,因为您正在寻找要像这样编写的代码。看起来是误导的管理要求或简单的无能。

10-02 08:51
查看更多