我是编程的新手,最近学习了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传递到需要访问的功能/类中?实施Getters并致电这些?直接使用g_state.variable1?
还是有更好的方法?
编辑:要更具体地说,我试图使用Pygame在Python上编写一款游戏,并正在考虑将我的游戏变量放入类,以便没有一堆全局变量。我不确定如何使用良好的设计访问这些变量,因此以后不会遇到麻烦。
您是对的,太多的全局变量不是一个好主意。污染的全球名称空间可能导致错误。
但是,不要为此而将它们放入课堂。如果您确实有很多变量,也许您应该考虑将程序拆分为多个模块。
还请理解,您不能像在JavaScript中那样真正地板条python中的全局变量。您的变量始终在模块下范围。
让我用一个例子说明。模块A.Py:
A = 42
模块B.Py:
import a
print(A)
你得到什么?NameError
。为什么?因为变量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
创建仅用于存储变量的类创建类。只有在您确实需要该类的多个实例(每个都有唯一的值)的情况下,才需要一个类。
但对于一个单一的全球状态,字典对象可以就此目的而言就足够了。您可以将其存储在专门用于配置和状态的模块中,如果需要:
conf.py
GAME_STATE = {
'level': 0,
'score': 0,
'misc': [1,2,3],
}
main.py
import conf
conf.GAME_STATE['score'] = 100
因此,您的其他模块只能导入conf.py
模块并访问状态命令。您可以在此对象中存储任何需要的类型。它还为您提供了一个方便的位置,可以添加功能,以在愿意的情况下序列将这些值序列到磁盘,并在程序的未来运行中重新读取它们,并将它们与配置选项保持一致。
否!构建VariableBox
将帮助您不是!
只需使用所需的VAR即可使用。如果您的全球量太多,那么应该被认为是全局的问题,以及应该与特定结构有关的问题。甚至在命名VAR或创建数组的难度,而不是var1, var2, var3, ...
。
课程设计用于构建对象,i。例如,用于创建特殊性不同但具有相同基础的事物。有价值的阶级是定义一个实体的东西,也是该实体的主要行为。
编辑:
python不提供可见性约束,因此您将无法通过简单地将其塞入类中 protect 数据;可以从类的任何地方访问条目。
创建Getters或仅仅维护类的实例只是决定与哪一个合作的问题。为了保持清晰的事物,最好是为游戏制作控制器,这将使游戏资产和游戏玩法之间成为此界面。
例如,在执行期间,您可以:
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
内部,您可以汇总相关的信息,因此您将在即将到来的函数中没有无数的参数列表。
无论如何,我无法告诉您哪种最好的使用;有很多人研究这些模块化问题,而我不是其中之一,所以这只是我对您的应用程序可以很好的看法。