我是编程新手,最近学过python和面向对象编程的基础知识。我知道有很多全局变量通常是一个坏主意,我可以将它们全部放入一个类中。这是正确的方法吗?
class GameState(object):
def __init__(self):
self.variable1 = 1
self.variable2 = 2
self.list = [3, 4, 5]
g_state = GameState()
而且,如果我想访问g_state中的变量,那么最好的方法是什么?
将g_state传递给需要访问的函数/类? 实施getter并调用它们? 直接使用g_state.variable1?
或者有更好的方法吗?
编辑:更具体地说,我正在尝试使用pygame在python中编写游戏,并且正在考虑将我的游戏状态变量放入类中,以便不会有一堆全局变量。我不确定如何以良好的设计访问这些变量,所以我以后不会遇到麻烦。答案 0 :(得分:4)
你是对的,太多的全局变量不是一个好主意。污染的全局命名空间可能会导致错误。
然而,不要为了它而将它们放入课堂。如果你真的有很多变量,你应该考虑将你的程序分成多个模块。
另外请理解,你不能像在JavaScript中那样在Python中创建全局变量。您的变量始终作为模块的范围。
让我举一个例子来说明。模块a.py:
A = 42
模块b.py:
import a
print(A)
你得到了什么? NameError
。为什么?因为变量A不是全局的,所以它在模块a
下。您需要使用a.A
来引用它。
没有必要在类下填充变量。它们位于模块下,充当命名空间,并且没有错误。
答案 1 :(得分:2)
创建一个仅用于存储变量的类是没有必要的。如果您确实需要该类的多个实例,每个实例都具有唯一值,则只需要一个类。
但是对于单个全局状态,字典对象就足够了。如果需要,可以将其存储在专门用于配置和状态的模块中:
<强> conf.py 强>
GAME_STATE = {
'level': 0,
'score': 0,
'misc': [1,2,3],
}
<强> main.py 强>
import conf
conf.GAME_STATE['score'] = 100
所以你的其他模块只能导入conf.py
模块并访问状态字典。您可以在此对象中存储所需的任何类型。它还为您提供了一个方便的位置,可以根据需要添加将这些值序列化到磁盘的功能,并在将来的程序运行中将它们读回来,并将它们与配置选项一起保存。
答案 2 :(得分:1)
有两种方法可以访问变量:一个全局对象或将一个实例传递给一个函数。第一个也是一个坏主意。第二个更好。但是不要用所有变量创建单个对象! (见第一条评论)。
如果绕过一个物体,还有很多事情需要考虑。如果合适的话,一个好主意是将事物作为成员函数来实现。
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
答案 3 :(得分:1)
NO !!!构建VariableBox
将帮助您不!
只需使用您想要的var,无论它适用于何处。如果你有太多的全局变量,那么它应该被视为全局变量,而应该与特定结构有什么关系。甚至在命名变量或创建数组时遇到困难,而不是var1, var2, var3, ...
。
类用于构建对象,i。例如,用于创建具体不同但具有相同基础的东西。有价值的类可以在某种程度上定义一个实体,以及该实体的主要行为。
修改强>:
Python不提供可见性约束,因此您无法通过简单地将数据填充到类中来保护数据;可以从类的实例所在的任何地方访问这些条目。
创建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
内,您可能会聚合相关信息,因此您在即将推出的功能中不会有无穷无尽的参数列表。
无论如何,我无法告诉你哪个是最好用的;有很多人研究这些模块化问题,我不是其中之一,所以这只是我对你的应用程序可以解决的问题的看法。