在 Python 3.5 中跨多个脚本使用 python 中的 'global'

Use of 'global' in python across multiple scripts in Python 3.5

[首先,对于我的代码我真的很抱歉,因为我知道它可能很难理解。我是去年才真正开始学Python的,我的老师自己也很难理解。]

我正在尝试在 Python 3.5.1 中制作基于文本的游戏,并将其分布在 4 个单独的 python 文件中:1 个包含主游戏,1 个包含库存系统, 1 具有其他功能,最后一个具有角色创建功能。

我想知道我应该如何使用全局变量和函数,并且在我的搜索中发现全局变量被视为解决问题的糟糕方法,但没有找到适合我的游戏的替代方法。在 How to make a save/load game for a text based python rpg? 中,他们使用 global 来定义 game_state 但没有别的,但我在函数中定义了数十个变量,以便于重复使用相同的代码。例如:

def expadd(amount):
    global level, totalxp, exp, expbound, p1, p2, p3, p4, p5
    print("\nYou gained",str(amount),"exp!")
    exp = exp + amount
    totalxp = exp
    while exp >= expbound:
        addpoints()
        charchange()
        thingymjig()
        expbound = int(p4 / p5 + 20)
        exp = exp - expbound
        level += 1
        time.sleep(1)
        print("\nLevel up! You are now level",str(level)+"!")
    time.sleep(1)
    expbound = int(p4 / p5 + 20)
    nextlevel = expbound - exp
    print("\nYou are",str(nextlevel),"exp away from the next level!")

这是处理函数的好方法吗?我不会想到你必须在玩家升级时输入所有这些代码,尽管从我在其他地方看到的情况来看,实际上没有人像我在这里那样使用这么多全局变量。 (p1-5 变量来自一个单独的函数,因此可以将它们重新定义为玩家等级,它们也应该在这个函数中吗?)

def addpoints():
    global charpoints
    charpoints = charpoints + int(level * 2)- int(level / 2) - 1

在这个部分中,charpoints(角色点数)是在玩家升级后添加的,并且为了方便使用而调用,而不是每次我需要时都输入所有代码。我在我的代码中多次使用这种功能,这是错误的吗?此外,有没有比跨多个脚本并使用大量函数和全局变量更简单的方法来制作易于阅读的代码?

我目前收到玩家输入的性别的 NameError,因为它来自另一个脚本中的函数,尽管它已全球化并导入到主文件中,我认为这是正确的:

from GAMEFUNCS import gender, charname, charpoints, charstrength, chardefence, charspeed

我需要将它导入到主文件中,以便我可以将其设置为保存,即使它在以下代码(和导入函数中)中被全球化,我仍然得到错误。

def savewrite():
    global qr, check, gender, charname, title, money, exp, totalxp, level
    global health, hp, lives, charpoints, charstrength, chardefence
    global charspeed, charintel
    with open("save.csv",'w',newline='')as s:
        csv_s = csv.writer(s)
        csv_s.writerow(["Quickrun"]+[qr])
        csv_s.writerow(["Checkpoint"]+[check])
        csv_s.writerow(["Gender"]+[gender])

出于您当前遇到的原因,全局变量不是一个好主意。举个例子:

a.py:

a = "a"

def print_a():
    print(a)

b.py

from a import a, print_a
a = "b"
print_a()

执行python b.py会打印什么?它将输出 "a",因为变量 a 仅在 b 模块的上下文中设置为 "b"。全局变量很难控制变量的访问和范围。最好将这样的状态放入一些数据结构中并将它们传递给函数。这样你也更通用,你可以为不同的对象重用函数。

示例:

def addpoints(character):

    character.charpoints = character.charpoints + character.level * 2 - (character.level / 2) - 1

(假设 character 类似于 namedtuple 或具有适当属性的东西)

这样你不仅可以避免全局变量,而且如果你想在团队中有多个人甚至敌人,你的函数也适用于其他角色,如配角或团队成员。

如果没有堆栈跟踪和生成它的代码,很难说出为什么会出现 NameError。我仍然希望我的回答能让您了解为什么全局变量可能不是一个好主意。