您有三个文件:main.py,second.py和common.py
common.py
#!/usr/bin/python
GLOBAL_ONE = "Frank"
Run Code Online (Sandbox Code Playgroud)
main.py
#!/usr/bin/python
from common import *
from second import secondTest
if __name__ == "__main__":
global GLOBAL_ONE
print GLOBAL_ONE #Prints "Frank"
GLOBAL_ONE = "Bob"
print GLOBAL_ONE #Prints "Bob"
secondTest()
print GLOBAL_ONE #Prints "Bob"
Run Code Online (Sandbox Code Playgroud)
second.py
#!/usr/bin/python
from common import *
def secondTest():
global GLOBAL_ONE
print GLOBAL_ONE #Prints "Frank"
Run Code Online (Sandbox Code Playgroud)
为什么secondTest不使用其调用程序的全局变量?如果事实上并非如此,那么称之为"全球性"的东西有什么意义呢?
为了获得secondTest(或我从main调用的任何外部函数)来识别和使用正确的变量,我缺少什么?
nkr*_*rkv 11
global对于这个模块而言意味着全局,而不是整个程序.当你这样做
from lala import *
Run Code Online (Sandbox Code Playgroud)
您添加的所有定义lala为当地人给这个模块.
所以在你的情况下你得到两份副本 GLOBAL_ONE
第一个也很明显的问题是为什么?
在某些情况下,全局变量是必要/有用的,但实际上很少.
您的问题在于命名空间.将common导入second.py时,GLOBAL_ONE来自该命名空间.导入secondTest时,它仍然GLOBAL_ONE从common.py 引用.
然而,你真正的问题在于设计.我想不出一个单一的逻辑很好的理由去实现一个全局变量这种方式.全局变量在Python中是一项棘手的业务,因为没有常量变量这样的东西.但是,惯例是当你想在Python中保持一些常量时,你可以命名它WITH_ALL_CAPS.人机工程学:
somevar = MY_GLOBAL_VAR # good!
MY_GLOBAL_VAR = somevar # What? You "can't" assign to a constant! Bad!
Run Code Online (Sandbox Code Playgroud)
做这样的事情有很多原因:
earth = 6e24
def badfunction():
global earth
earth += 1e5
print '%.2e' % earth
Run Code Online (Sandbox Code Playgroud)
真可怕
当然,如果您只是将其作为理解名称空间和global调用的练习,请继续.
如果没有,全局变量是A Bad Thing™的一些原因是:
balance或者您或其他人正在重用您的函数并且不考虑这一点时会发生什么?如果你在计算账户余额,突然间你要么太多,要么不够.像这样的虫子很难找到.如果你有一个需要值的函数,你应该将该值作为参数传递,除非你有一个非常好的理由.一个原因是拥有PI的全局 - 取决于您可能想要的精度需求3.14,或者您可能想要它3.14159265......但这是一个全局有意义的案例.可能只有少数或两个真实案例可以正确使用全局变量.其中一个案例是游戏编程中的常量.导入pygame.locals并使用KP_UP比记住响应该事件的整数值更容易.这些是规则的例外.
并且(至少在pygame中)这些常量存储在一个单独的文件中 - 仅用于常量.任何需要这些常量的模块都会导入所述常量.
编程时,编写函数将问题分解为可管理的块.优选地,功能应该做一件事,并且没有副作用.这意味着诸如calculatetime()之类的函数应该计算时间.它可能不应该读取包含时间的文件,并禁止它应该做一些事情,比如在某个地方写时间.它可以返回时间,并在需要时获取参数 - 这些都是函数要做的好的,可接受的事情.函数是您(函数的程序员)和使用该函数的任何人(包括您)之间的一种契约.访问和更改全局变量违反了该合同,因为该函数可以以未定义或预期的方式修改外部数据.当我使用该calculatetime()函数时,我希望它会计算时间并可能返回它,而不是修改响应我刚刚导入的模块时间的全局变量时间.
修改全局变量会破坏合同以及程序所采取的操作之间的逻辑区别.他们可以在您的程序中引入错误.它们使升级和修改功能变得困难.当你使用全局变量作为变量而不是常数时,死亡尖尖的牙齿等待着你!