Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在类中包装全局变量(python)_Python_Oop_Global Variables - Fatal编程技术网

在类中包装全局变量(python)

在类中包装全局变量(python),python,oop,global-variables,Python,Oop,Global Variables,我是编程新手,最近学习了python和面向对象编程的基础知识。我知道有很多全局变量通常是个坏主意,我可以把它们全部放在一个类中。这样做对吗 class GameState(object): def __init__(self): self.variable1 = 1 self.variable2 = 2 self.list = [3, 4, 5] g_state = GameState() 如果我想访问g_状态中的变量,那么最好的方法是

我是编程新手,最近学习了python和面向对象编程的基础知识。我知道有很多全局变量通常是个坏主意,我可以把它们全部放在一个类中。这样做对吗

class GameState(object):
    def __init__(self):
        self.variable1 = 1
        self.variable2 = 2
        self.list = [3, 4, 5]

g_state = GameState()
如果我想访问g_状态中的变量,那么最好的方法是什么

将g_状态传递给需要访问的函数/类? 实现getter并调用它们? 直接使用g_state.variable1

还是有更好的办法


编辑:更具体地说,我正在尝试使用pygame用python编写一个游戏,并考虑将我的游戏状态变量放入一个类中,这样就不会有一堆全局变量。我不确定如何使用良好的设计访问这些变量,这样我以后就不会遇到麻烦。

你是对的,太多的全局变量不是一个好主意。受污染的全局命名空间可能会导致错误

然而,不要为了上课而把他们放到课堂上。如果你真的有那么多的变量,也许你应该考虑把你的程序分成多个模块。 另外,请理解,您不能像在JavaScript中那样用Python包装全局变量。变量的作用域始终在模块下

让我举例说明。模块a.py:

A = 42
模块b.py:

import a

print(A)
你得到了什么<代码>名称错误。为什么?因为变量A不是全局变量,所以它位于模块
A
下。您需要使用
a.a
来引用它


不需要在类下填充变量。它们位于模块下,模块充当名称空间,没有任何错误。

访问变量有两种方法:一种全局对象或将实例传递给函数。总的来说,第一个也是个坏主意。第二个更好。但是不要创建一个包含所有变量的对象!(见第一条评论)

如果你绕过一个物体,还有很多事情要考虑。一个好主意是在合适的情况下将事物作为成员函数实现

class VariableBox(object):
    def __init__(self):
        self.variable1 = 1
        self.variable2 = 2
        self.list = [3, 4, 5]

    def do_something(self):
        self.variable1 = self.variable2 + 42
        return self.variable1

不!!!构建一个
变量框将帮助您而不是

只要使用您想要的var,不管它在哪里应用。如果有太多的全局变量,那么应该将哪些变量视为全局变量,哪些变量应该与特定结构相关,这是一个相当大的问题。甚至在命名变量或创建数组(而不是
var1、var2、var3,…
时都会遇到困难

类是为构建对象而设计的,即。e、 ,用来创造不同的事物,但有相同的基础。有价值的类在某种程度上定义了一个实体以及该实体的主要行为

编辑

Python不提供可见性约束,因此您无法通过简单地将数据填充到类中来保护数据;可以从类实例所在的任何位置访问这些条目

创建getter或简单地维护类的实例只是决定使用哪个getter的问题。为了使事情保持清晰,最好为游戏制作一个控制器,这将使游戏资产和游戏性之间的界面更清晰

例如,在执行过程中,您可以:

class Controller:

    def __init__():
        self.turn = 0
        self. ...

    def begin():
        self.turn += 1
        self.opening_scene()

class Gameplay:

    def __init__(self, num_players, turn, ...):
        self.turn = turn # if it happens you want to use this value in the game
        self.num_player = num_players

# Main loop
controller = Controller()
controller.num_players = int(raw_input("Number of players: "))

gameplay = Gameplay(controller.num_players, controller.turn)
while True:

    if gameplay.action == ...:
    elif ...:
        ...
    elif *next turn*:
        controller.next_turn() # to set things up to next turn
    else ...:
        ...
Controller
中,您可以聚合相关信息,这样在即将到来的函数中就不会有无穷无尽的参数列表


不管怎样,我无法告诉你哪一个是最好的;有很多人都在研究这些模块化问题,而我不是其中之一,所以这只是我对如何在你的应用程序上运行良好的观点。

创建一个仅用于存储变量的类是没有必要的。只有当您确实需要该类的多个实例时,才需要该类,每个实例都具有唯一的值

但对于单个全局状态,dictionary对象就足以满足此目的。如果需要,可以将其存储在专门用于配置和状态的模块中:

conf.py

GAME_STATE = {
    'level': 0,
    'score': 0,
    'misc': [1,2,3],
}
import conf

conf.GAME_STATE['score'] = 100
main.py

GAME_STATE = {
    'level': 0,
    'score': 0,
    'misc': [1,2,3],
}
import conf

conf.GAME_STATE['score'] = 100

因此,您的其他模块只需导入
conf.py
模块并访问state dict即可。您可以在此对象中存储所需的任何类型。它还为您提供了一个方便的位置,可以添加将这些值序列化到磁盘(如果需要)的功能,并在以后的程序运行时读取这些值,并将它们与配置选项一起保存。

您有多少个变量?您是否遇到命名冲突?这感觉非常Javaeqsque…我还没有那么多变量,可以使用全局变量轻松实现它,而不会出现命名冲突或问题。但是我的印象是使用globals不是一条好路?@user75909我已经在我的帖子中添加了一个编辑,但是如果您需要任何进一步的帮助,您必须指定这些变量的用法。谢谢Rubens。我编辑了我的主要帖子,指定它是为了一个游戏。至于单个变量,你说得对,所以这是关于增加回合数、使用药剂、失去生命等等。我理解使用这样的类,但这不是我要问的。更具体地说,我正试图使用pygame用python编写一个游戏,并考虑将我的变量放入一个跟踪游戏状态的类中,这样就不会有一堆全局变量。@user75909那么,你似乎有了一个目的,所以完全可以有一个名为
State
的类,这将保留执行的具体细节信息,甚至可能提供一些服务,如返回玩家数量、玩的回合数、剩余尝试次数等。VariableBox只是我使用的一个占位符名称,因为我的原始帖子没有指定制作游戏,抱歉:p你的回答是不是意味着我应该为每个变量编写一个getter函数?我应该将GameInfo的实例传递到