取决于属性的属于类的对象的方法

时间:2018-12-17 11:55:43

标签: python class oop methods

我的担心与one question posted here有关,但是这次是指Python语言而不是C#。

我的目标是使用相同的类来实例化(两个)共享某些方法(但不是全部方法)的不同对象。我得出的结论是,最有效的方法(如果存在)可能是添加一个属性,该属性可以根据其值访问一种或另一组方法,同时共享这些方法用于两种情况。 这实际上可以在Python中实现吗?如果没有,您将如何建议我处理此问题?

先谢谢您,并致以最诚挚的问候。

编辑#1:实际上,我还有一个关于在这种情况下使用Factory的小问题,该问题与其余子类共享的更多参数和函数的使用有关。这是定义我的问题的正确方法吗?可以将“ init”和“ sharedFunction”方法与“工厂”方法分开定义吗?

class Object:

    def __init__(self, serial, np, t):
        self.serial = serial
        self.np = np
        self.t = t

    # Factory method
    def factory(model): 
        if model == 'modelA':
            return ModelA()
        if model == 'modelB':
            return ModelB()

    # Shared function
    def sharedFunction(self):
        pass

class ModelA(Object):

    def function1(self):
        self.t.sleep(10)

以便稍后我们可以实例化这些对象并将其用作:

>>> modelA = Object.factory('modelA')
>>> modelA.function1()

非常感谢您的时间。

编辑#2(在注释#9之后): 关于超类工厂函数中属性的定义,还有一件事对我来说还不够清楚。使用特定的值进行初始化是强制性的还是仅使用构造函数提供的值(对我来说是有意义的)进行初始化就可以了?

class Object(object):

    def __init__(self, serial, np, t):
        self.serial = serial
        self.np = np
        self.t = t

    # Factory method
    @staticmethod
    def factory(model): 
        if model == 'modelA':
            return ModelA(serial, np, t) # Here is where I am given an error message. Must I initialize the attributes of modelA and modelB with specific values? Why can't I do so for instance either with self.serial or just serial as I just created the constructor above?
        if model == 'modelB':
            return ModelB(serial, np, t) # Same as above

    # Shared function
    def sharedFunction(self):
        pass

class ModelA(Object):

    def __init__(self, serial, np, t, other_stuff):
        super(ModelA,self).__init__(serial, np, t)
        self.other_stuff = other_stuff

    def function1(self):
        self.t.sleep(10)

以便稍后我们可以实例化这些对象并将其用作:

>>> modelA = Object.factory('modelA', other_stuff)
>>> modelA.function1()

1 个答案:

答案 0 :(得分:0)

您所描述的内容听起来很像factory。最简单的形式可以通过以下方式实现:

class Animal:
    @staticmethod
    def factory(kind):
        if kind == 'Cat':
            return Cat()
        elif kind == 'Bird':
            return Bird()

class Cat(Animal):
    def say(self):
        return 'Meow'

class Bird(Animal):
    def say(self):
        return 'Chirp'

现在您可以使用Animal方法实例化factory(),该方法将根据kind参数自动选择一个子类:

>>> bird = Animal.factory('Bird')
>>> bird.say()
'Chirp'

编辑:

可以在基类中定义其他方法,例如__init__()sharedFunction()。但是,要使子类可以访问父类属性(self.serial等),必须调用父类构造函数。这可以通过两种方式完成:

  1. 按原样重用父类构造器
  2. 在子类中重写构造函数,并从中调用父类构造函数:

    class ModelA(Object):
        def __init__(self, serial, np, t, other_stuff):
            # Note: in Python 2, this requires `Object` to inherit from `object`
            super(ModelA, self).__init__(serial, np, t)
            self.other_stuff = other_stuff
    

在两种情况下,在factory()中创建对象时,都必须将相关参数传递给构造函数。在(1)中,这意味着您必须执行以下操作:

if model == 'modelA':
    return ModelA(serial=42, np='p', t=0)

在(2)中,您必须提供添加的所有其他参数:

if model == 'modelA':
    return ModelA(serial=42, np='p', t=0, other_stuff='something')

也不必将factory()定义为@staticmethod,以使其在没有特定实例的情况下可调用。