如何在Python中更改全局变量

10

我试图在程序的后面更改一个变量。我在程序开头声明了一个全局变量,并希望在程序下方的不同函数中更改该变量。我可以通过再次在函数内声明变量来实现这一点,但我想知道是否有更好的方法。下面是一些测试代码,以解释我的意思。

ID = 'No'
project = ("Yep"+ID) # ID added with 'No' value which I later want to change

def pro():

    ID = "YES"
    print ID

def pro1(ID):

    # I could declare project again to get this to work, but I would like to avoid this
    print project # I want this to print with the new ID number.

if __name__ == '__main__':
    pro()
    pro1(ID)

有人有什么想法吗,谢谢

我尝试过使用global变量,但是当我这样做时,project变量仍然打印出YepNo而不是YepYES。 我希望来自函数pro的新变量可以更改project变量中的变量。


你想要项目的值也随之改变吗?如果是这样,那么你应该为它创建一个类。 - Ritwik Bose
3
虽然与问题无关,但是我有点被你把本地变量“myObject”设置为没有返回语句的函数的返回值所搞糊涂了。虽然这样可以工作(该值设置为None),但是它是毫无意义的,并且令人想,“他到底在想什么”。请注意,此举是不必要的。 - ddaa
2
Python中的字符串是不可变的。当进行字符串连接时,就像你的“project”赋值一样,你正在创建一个新的字符串。没有办法通过改变ID的值来稍后更改“project”。 - Alan Franzoni
3
请不要多次使用if __name__ == '__main__':这个语句。谢谢。 - S.Lott
1
另外,“predeclared variable”是什么意思?Python没有声明,所以这个标题没有任何意义。 - S.Lott
6个回答

12

要更新全局变量,您可以使用:

global ID
ID="Yes"

在将变量分配给ID = "YES"之前

但是更改ID不会对项目变量产生任何影响,project = ("Yep"+ID),因为project已经是一个字符串

您需要创建一个类似的函数

def getprojectname(ID):
    return project+ID
整个程序可能像这样。 更新: ...已移除。

要更改全局变量,您应将其声明为全局变量。 - unbeknown
2
我认为这个例子的代码风格真的很糟糕...即使你回答了问题,你也在鼓励不当的编程。 - Alan Franzoni
1
是的,没错,我知道,我只是不想动他的代码,现在已经删除了。 - YOU

7
注意,您已经多次犯了错误。
虽然您可以使用global语句来更改全局变量(虽然这种做法不被鼓励,因为最好使用函数参数和返回值),但这不会更改已分配的其他值。例如,即使您重新分配ID,也不会重新分配project。另外:您的函数没有返回值,给它们的返回值分配一个名称是没有意义的,并且使用全部大写名称(ID)作为变量是一个坏习惯,因为惯例是将它们用于常量。
这应该让您清楚全局变量的工作方式:
myid = ''
project = ("Yep"+myid) #ID added with no value which I later want to change

def mutate_id():
    global myid
    myid = "YES"

def mutate_project():
    global project
    project = ("YEP" + myid)

if __name__ == '__main__': 
    print "myid", myid
    print "project ", project
    print

    mutate_id()

    print "myid", myid
    print "project ", project
    print

    mutate_project()

    print "myid", myid
    print "project ", project
    print

但最好的方法是避免使用全局变量:

def get_new_id(old):
    return "YES"

def get_new_project(old):
    return ("YEP" + myid)

if __name__ == '__main__': 
    myid = ''
    project = ("Yep"+myid) 

    print "myid", myid
    print "project ", project
    print

    myid = get_new_id(myid)

    print "myid", myid
    print "project ", project
    print

    project = get_new_project(project)

    print "myid", myid
    print "project ", project
    print

这将使所有代码交互清晰,并防止与全局状态更改相关的问题。

进一步解释一个小点:project = ("Yep"+ID) 立即被计算:变量 ID 被扩展为字符串 'No',然后附加到 "Yes" 上形成字符串 'YepNo',该字符串立即分配给变量 project。稍后更改 ID 不会产生影响,因为 project 已经有了它的值。 - James Polley
是的,我直接在原始帖子上对此进行了评论 :-) - Alan Franzoni

2

这只解决了代码中的一些问题:例如,它并没有改变project在第二行被赋值且从未更改的事实,而OP想要的部分是在ID更改时更新project - James Polley
链接似乎已经损坏。 - Matteo Monti

1
在你的代码中有两个问题。第一个问题是关于改变ID变量,可以通过使用global来解决。
第二个问题是你的代码计算了项目字符串,但之后项目不知道ID的存在。
为了避免代码重复,你可以定义一个函数来计算项目。
所以我们有:
ID = 'No'
def GetProject():
    return "Yep"+ID

def pro():
   global ID
   ID = "YES"
   print ID

print GetProject()

pro()

print GetProject()

-1

你可以进行变异而无需重新分配:

variables = {}
def pro():
    if variables['ID'] == '':
        variables['ID'] = 'default'

-1

为什么不使用字典呢?

>>> attr = {'start':'XXX', 'myid':'No'}
>>> 
>>> def update_and_show(D, value = None):
...     if value:  D['myid'] = value
...     print D['start'] + ' ' + D['myid']
... 
>>> update_and_show(attr)
XXX No
>>> update_and_show(attr, 'Yes')
XXX Yes
>>> update_and_show(attr, 'No')
XXX No
>>>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接