我有一些代码用于解决一个名为nurikabe的益智游戏,最近我将其重写为OOP (仍在学习),并具有以下结构:
# CNurikabe.py
from includes import Board, Validation, Heuristics
class CNurikabe(object):
...
# CValidation.py
from includes import Board, Heuristics
class CValidation(object):
...
# CHeuristics.py
from includes import Board
class CHeuristics(object):
...
# CBoard.py
class CBoard(object):
def __init__(self, filename):
# Vars shared by every class
self.x, self.y, self.z, self.t = self.parseData(filename)
# run.py
from CNurikabe import CNurikabe
nurikabe = CNurikabe()
nurikabe.solve('output')
# includes.py
from CBoard import CBoard
Board = CBoard('data.dat')
from CHeuristics import CHeuristics
Heuristics = CHeuristics()
from CValidation import CValidation
Validation = CValidation()CBoard类具有必须在所有其他类之间共享的信息(如板尺寸、数字坐标等),我还希望它被实例化一次,如果可能的话,防止依赖注入(例如,不必要地将文件名传递给每个类init方法)。
需要这些类来访问以下内容:
CValidation类使用: CBoard和CHeuristics
CHeuristics类使用: CBoard
CNurikabe类使用: CBoard、CValidation和CHeuristics
我所拥有的代码就像预期的那样工作。我可以按我想要的方式在其他类中调用其他类的方法,例如:
# CNurikabe.py:
class CNurikabe(object):
def someFunc(self):
for i in range(Board.dimensionx):
Heuristics.doSomeStuff()
Validation.doSomeMore()但我读过太多关于全球化是如何邪恶的书了。另外,includes.py内部的代码有点麻烦,因为如果我更改导入的顺序,程序就不会运行,抱怨无法导入一些名称。
我还尝试了另一种方法,只在全局实例化CBoard类,然后,对于其他类,创建我需要的类的实例。但我觉得这有点重复,例如,在每个类中创建一个独特的CHeuristics全局实例,这仍然不能解决CBoard全局问题。
我还考虑在每个类的init中创建一个实例,但是代码将非常冗长,必须调用self.Heuristics.doSomeStuff()
那么,我的问题是,怎样才能更好地构建这个体系呢?我读过一些关于单例模式(因为这是一个小项目)的文章(因为它是一个小项目),以及为C++和PHP这样的多种语言使用的无穷无尽的方法。实际上,我所做的方式类似于"extern实例“;在C++中实现它的方式很久以前,我正在从事一个具有这种风格的C++项目,而且我喜欢它,虽然类实例是全局的,但它没有看到任何问题。
发布于 2013-02-02 09:41:09
全球都是邪恶的。但是,您可能需要一种将一些东西封装在一起的单例模式。我从C++和Python的经验是,您可以很好地使用混合字符的语言,并使用一个模块的作用,单例。(仔细想想,模块变量扮演着单例成员变量的角色,模块中的普通函数类似于单例的方法。)
这样,我建议将板功能放入board.py启发式功能到heuristic.py中,.,将方法转换为函数,将self.variable转换为variable,并使用:
import board
import heuristic
import validation
...
class CNurikabe: # the explicit (object) base class is not needed in Python 3
def someFunc(self):
for i in range(board.dimensionx):
heuristics.doSomeStuff()
validation.doSomeMore()将import board看作是获得对单例实例的引用--实际上是这样,因为模块对象只有一个实例。而且它在语法上将与您以前的代码一样--除了获取实例(模块)将更容易。
更新:一旦需要更多实例,就应该在类中重新思考。然而,在Python中传递对象是非常廉价的操作--您只复制引用值(从技术上讲是地址,即4或8个字节)。一旦获得了引用值,就可以轻松地将其赋值给局部变量。( Python中的每个赋值都意味着复制引用值,从而共享对指定对象的访问。这样,实际上不需要全局变量,也没有使用全局变量的借口。
使用局部变量,语法再次保持不变。
https://stackoverflow.com/questions/14659328
复制相似问题