Метод принадлежности к объекту из класса в зависимости от атрибута - PullRequest
0 голосов
/ 17 декабря 2018

Моя проблема связана с одним вопросом, размещенным здесь , но на этот раз речь идет о языке Python, а не C #.

Я намерен использовать один и тот же класс для создания (двух) разныхобъекты, которые разделяют некоторые методы, но не все.Я пришел к выводу, что наиболее эффективный способ сделать это, , если он существует , - это добавить атрибут, который может предоставлять доступ к тому или иному набору методов в зависимости от его значения, при этом разделяя те, которыеиспользуются в обоих случаях. Возможно ли это в Python ?Если нет, то как бы вы порекомендовали мне заняться этим вопросом?

Заранее благодарим вас и наилучшими пожеланиями.

РЕДАКТИРОВАТЬ # 1: У меня есть еще одинНебольшой вопрос, касающийся использования Factory в этом контексте, связанный с использованием большего количества аргументов и функций, совместно используемых остальными подклассами.Будет ли это правильный способ определения моей проблемы?Могут ли методы 'init' и 'sharedFunction' быть определены отдельно от метода 'factory'?

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 голосов
/ 17 декабря 2018

То, что вы описываете, очень похоже на фабрику .В простейшей форме это может быть реализовано следующим образом:

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, чтобы его можно было вызывать без определенного экземпляра.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...