Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/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_Design Patterns_Inheritance_Singleton - Fatal编程技术网

当您希望创建派生的单例时,使用Python模块的替代方案

当您希望创建派生的单例时,使用Python模块的替代方案,python,design-patterns,inheritance,singleton,Python,Design Patterns,Inheritance,Singleton,在Python项目中,我需要为用户提供各种概念的单个实例,让我们称它们为“狗”、“猫”和“鹦鹉”。它们有一些共同的功能,比如sleep()、eat()和is_dead(),为了代码重用的目的,我想把它们放在“pet”的概念中。可以有多只宠物,但每种类型只有一只宠物 我相信Python模块不可能从另一个模块继承,因此如果我只想使用模块,我就必须抛弃“宠物”概念,在每个“狗”、“猫”和“鹦鹉”模块中重复代码(睡眠、进食等)。或者创建一个“宠物”模块,然后在其他每个模块中使用“从宠物导入*”,据我所知

在Python项目中,我需要为用户提供各种概念的单个实例,让我们称它们为“狗”、“猫”和“鹦鹉”。它们有一些共同的功能,比如sleep()、eat()和is_dead(),为了代码重用的目的,我想把它们放在“pet”的概念中。可以有多只宠物,但每种类型只有一只宠物

我相信Python模块不可能从另一个模块继承,因此如果我只想使用模块,我就必须抛弃“宠物”概念,在每个“狗”、“猫”和“鹦鹉”模块中重复代码(睡眠、进食等)。或者创建一个“宠物”模块,然后在其他每个模块中使用“从宠物导入*”,据我所知,这被认为是不好的做法

或者,我可以创建一个“pet”类(从实现基类的单例派生),然后从中派生“dog”、“cat”和“parrot”类。然而,我看到大多数关于Python中单例模式的讨论都暗示该模式不是一个好主意

因此,我想避免我印象中的三个方面是不好的做法:

  • 不同源文件之间的代码复制
  • “from x import*”的使用
  • 单例设计模式的使用
然而,我无法通过上述任何解决方案实现这三个目标。我很想采用单例设计模式,因为它似乎是“最不坏”的选择。有没有一种方法可以实现我想要的,同时避免所有三个问题,并且不引入任何其他不良做法?

你说:

我认为Python模块不可能从另一个模块继承

我不确定您的意思是什么-似乎您遇到的问题是简单的类继承,您自然会使用另一个模块来实现这一点:

文件:pet.py

class Pet():
  def __init__(self):
      self._type = "Generic pet"

  def sleep(self):
      print self.type, "is sleeping"
文件dog.py

import pet

class Dog(pet.Pet):
       number_of_dogs = 0

       def __init__(self):
          if (Dog.number_of_dogs != 0):
               raise Exception("Grrrr...")
          pet.Pet.__init__(self)   # assuming no diamond inheritance of animals
          self.type = "The Dog"
          Dog.number_of_dogs = 1

       def Bark(self):
          print "Woof"
提示符>python

>>> import pet
>>> import dog
>>> c = dog.Dog()
>>> d = dog.Dog()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "dog.py", line 8, in __init__
    raise Exception("Grrrr...")
Exception: Grrrr...
>>> c.sleep()
The Dog is sleeping
>>> c.Bark()
Woof
>>>
>>导入宠物
>>>进口狗
>>>c=狗。狗()
>>>d=狗。狗()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“dog.py”,第8行,在init中__
引发异常(“Grrrr…”)
例外:Grrrr。。。
>>>c.睡眠()
狗在睡觉
>>>c.树皮()
汪汪
>>>

我将遵循一些编写良好的教程,并结合

有必要摆脱将类实例视为生成可与之交互的继承结构的唯一方法的想法:可以使用类方法(而不仅仅是实例方法)创建类

因此,可以根据需要创建继承结构,其中
鹦鹉
继承自
宠物
。然后,通过使用classmethods而不是实例方法,可以在不实例化的情况下与这些类进行交互,因此不需要任何单例模式。如果需要任何状态,则可以使用类属性在类级别保持该状态

classmethods的使用有很好的文档记录

例如:

class Pet(object):
    @classmethod
    def is_dead(cls):
        return False

class Dog(Pet):
    @classmethod
    def bark(cls):
        print "woof"

if __name__ == "__main__":
    if not Dog.is_dead():
        Dog.bark()

用你的例子来说有点难,但是这些是否真的需要是单独的实例呢?它们可能是共享动物超类上的类方法吗?为什么不创建共享类的实例呢
dog=Pet(…)
则是模块中的全局变量。您总是可以将附加功能附加到该实例。虽然建议不要使用宠物导入的
*
,但宠物导入的
狗、猫、鹦鹉的
则不是。根据我的经验,大多数人接触单身人士都是过度设计了他们的问题。在Python中,如果有人通过创建多个单例类实例来攻击自己,这不是您的问题。只需创建
Pet
Cat
Dog
Parrot
类,分别创建后三个类的一个实例,并使用这些实例记录API。如果必须在创建实例后立即使用
del Cat、Dog、Parrot
,以防止轻松导入,通常只需使用即可。是的,或者从Pet生成子类,只使用类而不是实例@那么classmethod就是你的朋友了。