as we all know, Python performance when it comes to accessing global variables drops down significantly.
不是“显著”-局部查找确实有点便宜,但定义局部变量也有成本,因此除非您在非常紧的循环中查找全局变量,否则您注意到差异的机会非常小,然后您可以始终在本地别名全局变量,即:FOO = 42
def foo():
for i in range(100000000):
x = i * FOO
到
^{pr2}$
换句话说,在性能成为一个真正的问题并且探查器将此全局查找确定为一个主要瓶颈(这确实不太可能)之前,您不应该担心这里的性能问题,即便如此,我还是很怀疑你最终是否会得到任何显著的提升——如果全局查找的成本对于你的应用程序来说已经太高了,那么Python并不是正确的工具,是时候用C重写这一部分了I could move those constants, that I use only in one method, to the local scope of the methods I use them from, but that removes readability.
而且,如上所述,不一定会提高性能:>>> import dis
>>> import timeit
>>>
>>> FOO = 42
>>> def foo1():
... return FOO
...
>>> def foo3():
... foo = 42
... return foo
...
>>> dis.dis(foo1)
2 0 LOAD_GLOBAL 0 (FOO)
3 RETURN_VALUE
>>>
>>> dis.dis(foo3
... )
2 0 LOAD_CONST 1 (42)
3 STORE_FAST 0 (foo)
3 6 LOAD_FAST 0 (foo)
9 RETURN_VALUE
>>> timeit.timeit("func()", "from __main__ import foo1 as func")
0.06334185600280762
>>> timeit.timeit("func()", "from __main__ import foo3 as func")
0.06805109977722168Then I will still have some globals which are used in multiple methods and I really cannot hide them in the scope of only one function. What's the solution to that?
到底有什么问题?在I saw a guy making a game (...) you can see that he just has one big file constants.py with a hell lotta global variables there (without global keyword).
在模块顶层定义的所有名称(通过赋值、导入、函数定义或类定义)都是该模块的“全局”名称(这是Python中唯一一种“全局”名称,没有“应用程序范围的全局变量”)。global关键字只能在函数中使用,并且只有当您确实想在函数中分配给全局时才使用,这是我们都知道不应该做的事情,是吗?在Is this a good practic?
取决于这些“常量”是如何和在哪里使用的。如果你有一个以上的模块使用的常量,并且这些模块之间没有其他依赖关系,那么这是有意义的,但是大多数时间常数要么只被一个模块使用,要么其他使用它们的模块也需要来自同一个模块的其他名称(函数、类等)。在
长话短说:常量没有什么特别的,它们只是引用对象的名称(你可能没有意识到,但你所有的函数和类也是“常量”),因此,您只需要对其他模块应用相同的指导原则:您的模块应该具有强大的内聚性(模块中的所有内容都是强相关的)和低耦合性(您的模块依赖于尽可能少的其他模块)。从这个角度来看,在一个文件中定义数十个不相关的常量是完全错误的,它破坏了内聚性并引入了强耦合。在
请注意,您可能还有一些其他原因可以这样“集中”常量(至少是其中的一部分):使配置更简单-但这只适用于您希望使其可配置的常量(您会使值“pi”可配置吗?),是一个完全不同的问题。在