如何在多个Python模块中更改变量?

时间:2014-06-27 05:42:48

标签: python class python-3.x scope

我一直坚持试图让这个工作几个小时。我对编程很缺乏经验,所以我很抱歉,如果我想做的事情完全是荒谬的。如果可能的话,我想避免创建.txt,.config或.JSON(或任何其他非.py文件)文件来保存变量,以简化起见。

我希望我的程序有一个'体验'变量。在我的游戏中,我希望能够在游戏中的任何给定实例中以多个不同的文件添加此变量。 (还有大约10个其他变量,我也希望程序能够在多个模块中使用)。如果你今天看到我提出一个非常类似的问题,我很抱歉。但我觉得我已经如此接近解决这个错误,然后它最终无法正常工作。我太近了!

#File1.py
experience = 0
from File2 import givexp
class game:
    def give_xp(self,given_xp):
        global experience
        experience += given_xp
        print('Experience: ',experience)
player = game()
def main():
    print('1) give xp')
    print('2) give 500 xp')
    donow = input()
    if donow == '1':
        givexp() #this is in File2.py
    if donow == '2':
        player.give_xp(500)
while 1:
    main()
 
#File2.py
def givexp():
    from main import player
    player.give_xp(200)

现在唯一的问题是,当我第一次按程序时,程序会问我该怎么做,没有任何反应,它会问我该怎么做。我认为这是因为File2中的import语句。所以当我添加

if __name__ == '__main__':
    while 1:
        main()

这完全弄乱了程序,现在这两个文件将有自己的经验变量,这是我无法理解的。 我知道我可以将我的课程改为常规功能并且有经验返回,但在我的实际游戏中,会有更多的变量要跟踪,我想以其他方式做到这一点而不是“var1,var2,var3等= part_one_of_game()

现在使用此代码的所有内容都按照我想要的方式工作,除了那个讨厌的bug,游戏在第一次运行时询问玩家他或她想做什么两次。对此有一个简单的解决方法吗?

4 个答案:

答案 0 :(得分:1)

此处one.py

from game import gamehandle
from two import givexp
def main():
    print('1) give xp')
    print('2) give 500 xp')
    print('3) Show current XP')
    donow = input()
    if donow == '1':
        givexp(200) #this calls the function in two.py
    elif donow == '2':
        gamehandle.give_xp(500)
    elif donow == '3':
        print(gamehandle.experience)
if __name__ == '__main__':
    while 1:
        main()

这里two.py

from game import gamehandle
def givexp(ammount):
    gamehandle.load_variables()
    gamehandle.give_xp(ammount)

最后,game.py

import pickle
from os.path import isfile
class Game(object):
    def __init__(self):
        self.experience = 0
        self.health = 0
        self.loadedFromDisk = False
    def give_xp(self, given_xp):
        self.experience += given_xp
    def save_variables(self):
        with open('game.dump', 'wb') as fh:
            pickle.dump({'xp' : self.experience, 'hp' : self.health}, fh)
    def load_variables(self):
        if not self.loadedFromDisk:
            if isfile('game.dump'):
                with open('game.dump', 'rb') as fh:
                    data = pickle.load(fh)
                    self.experience = data['xp']
                    self.hp = data['hp']
            self.loadedFromDisk = True

gamehandle = Game()

致电python3 one.py开始游戏 文件的命名惯例很糟糕,我得说..但它确实有用。

在这里,您可以通过gamehandle直接修改游戏变量,这是Game()类的全局实例,并且可以在导入from game import gamehandle的整个文件中访问它。您还可以动态保存和加载变量"致电:

gamehandle.save_variables()

gamehandle.load_variables()

与给出的其他示例相比,此语法有效且经过测试...
我还说这是访问Game实例的更好方法,因为您可以简单地执行from game import gamehandle来访问self.experience,这样可以让事情变得更容易并保持与之相比,实例的跟踪是轻而易举的,让我们通过5个嵌套函数传递它。

作为最后一点,请考虑从一开始就将{{1}}更改为字典以节省时间和工作,因为最终您可能希望通过字符串访问变量,这样做将会是一本字典很清洁。

答案 1 :(得分:0)

您可以使用内置的pickle module

用法:

import pickle

# to save variable state
with open('state.pickle', 'w+') as f:
    pickle.dump([x, y, z], f)

# to load variable state
with open('state.pickle', 'r') as f:
    x, y, z = pickle.load(f)

其中 - x,y,z - 是您要保存/加载的变量。

答案 2 :(得分:0)

我认为循环导入并不是一个好主意,因为这会导致分层问题。

最好将game类移出__main__模块

至于您的问题,请考虑使用game属性来存储变量以跟踪

# game.py
class Game(object):
    def __init__(self):
        self.experience = 0
    def give_xp(self,given_xp):
        self.experience += given_xp
        print('Experience: ',experience)

#File2.py
def givexp(player):
    player.give_xp(200)

#File1.py
from game import Game
player = Game()
def main():
    print('1) give xp')
    print('2) give 500 xp')
    donow = input()
    if donow == '1':
        givexp(player) #this is in File2.py
    if donow == '2':
        player.give_xp(500)
if __name__ == '__main__':
    while 1:
        main()

答案 3 :(得分:0)

好问题,揭露了一个重要的问题'。每个模块都有自己的命名空间。即使导入文件2,命名空间也会完整隔离。这种隔离很好,因为你可以在两个模块中使用相同名称的函数。这就是问题所在:你导入了File 2,它仍然在自己的命名空间中查找变量。错误告诉我们:

Traceback (most recent call last):
  File "File1.py", line 19, in <module>
    main()
  File "File1.py", line 15, in main
    givexp() #this is in File2.py
  File "/home/pi/File2.py", line 3, in givexp
    player.give_xp(200)
NameError: global name 'player' is not defined

您可以使用可爱的global关键字来解决此问题。但是,嘿,你在课程的正确轨道上,所以只需确保模块2中的函数适用于你的实例,在这种情况下player即将player传递给函数:

givexp(player)

并更改File2,以便您的函数接受对象:

#File2.py                                                                       
def givexp(obj):
    obj.give_xp(200)