2 回答
TA贡献1895条经验 获得超7个赞
好吧,我将停止查看您的代码,而我的答案只是基于您的意见:
我有一个基类,实际上我的应用程序中的所有其他类都可以扩展(只是一些应用程序内功能的基本约定;也许应该只是一个接口)。
这将ThesaurusBase在下面的代码中
该基类旨在容纳一个词库类的单例,该类通过推断一些同义词(即{'yes':'yep','ok'})为用户输入提供一定的灵活性。
那将是ThesaurusSingleton,您可以使用更好的名称进行调用并使其真正有用。
class ThesaurusBase():
def __init__(self, singleton=None):
self.singleton = singleton
def mymethod1(self):
raise NotImplementedError
def mymethod2(self):
raise NotImplementedError
class ThesaurusSingleton(ThesaurusBase):
def mymethod1(self):
return "meaw!"
class Thesaurus(TheraususBase):
def __init__(self, singleton=None):
TheraususBase.__init__(self, singleton)
def mymethod1(self):
return "quack!"
def mymethod2(self):
return "\\_o<"
现在,您可以按以下方式创建对象:
singleton = ThesaurusSingleton()
thesaurus = Thesaurus(singleton)
编辑:基本上,我在这里所做的是建立一个“基础”类,该类只是一个接口,该接口定义了其所有子类的预期行为。该类ThesaurusSingleton(我知道这是一个糟糕的名字)也正在实现该接口,因为您说过它也有,并且我不想讨论您的设计,所以您可能总是有奇怪的约束的充分理由。
最后,您是否真的需要在定义单例对象的类中实例化您的单例?尽管可能有一些骇人听闻的方法,但是通常会有更好的设计来避免出现“骇人听闻”的部分。
我的想法是,无论您创建单身人士,都应该明确地做到这一点。那就是“ Zen of python”:显式比隐式好。为什么?因为这样一来,阅读您的代码的人(也许六个月后便会成为您)将能够了解正在发生的事情以及编写该代码时您在想什么。如果您尝试使事情变得更隐式(例如使用复杂的元类和怪异的自继承),您可能会想知道这段代码在不到三周的时间内会做什么!
我并不是说要避免这种选择,而只是在没有简单选择的情况下才使用复杂的选择!
根据您所说的,我认为我提供的解决方案可以作为起点。但是当您专注于一些晦涩但不是非常有用的hacky东西而不是谈论您的设计时,我不确定我的示例是否合适,并向您提示了设计。
edit2:还有另一种方法可以实现您想要的内容(但请确保这确实是您想要的设计)。您可能想使用将对类本身(而不是实例)起作用的类方法,从而使您能够存储自身的类范围的实例:
>>> class ThesaurusBase:
... @classmethod
... def initClassWide(cls):
... cls._shared = cls()
...
>>> class T(ThesaurusBase):
... def foo(self):
... print self._shared
...
>>> ThesaurusBase.initClassWide()
>>> t = T()
>>> t.foo()
<__main__.ThesaurusBase instance at 0x7ff299a7def0>
并且您可以initClassWide在声明ThesaurusBase的模块级别调用该方法,因此,每当导入该模块时,该模块都会加载单例(导入机制确保python模块仅运行一次)。
TA贡献1848条经验 获得超6个赞
简短的答案是:
不要从超类构造函数实例化一个子类的实例
更长的答案:
如果您要这样做的动机是词库是一个单例事实,那么最好使用类(Thesaurus)中的静态方法公开该单例,并在需要该单例时调用此方法
添加回答
举报