Должен ли я использовать абстрактные методы в этом сценарии Python? - PullRequest
2 голосов
/ 16 января 2011

Я не уверен, что мой подход - хороший дизайн, и я надеюсь, что смогу получить совет.Я думаю о чем-то вроде абстрактного метода, но в этом случае я хочу, чтобы метод был необязательным.Вот как я это делаю сейчас ...

from pymel.core import *

class A(object):
    def __init__(self, *args, **kwargs):
        if callable(self.createDrivers):
            self._drivers = self.createDrivers(*args, **kwargs)
            select(self._drivers)

class B(A):
    def createDrivers(self, *args, **kwargs):
        c1 = circle(sweep=270)[0]
        c2 = circle(sweep=180)[0]
        return c1, c2

b = B()

В приведенном выше примере я просто создаю 2 окружности в PyMEL для Maya, но я полностью намерен создать больше подклассов,может вообще не иметь метода createDrivers!Поэтому я хочу, чтобы это было необязательным, и мне интересно, если мой подход - ну, если мой подход может быть улучшен?

Ответы [ 3 ]

3 голосов
/ 16 января 2011

У вас все еще есть проблема, когда вы унаследуете свой класс B, и это вызовет A.__init__, и если вы не реализуете createDrivers в подклассе, эта строка callable(self.createDrivers) выдаст ошибку как createDrivers не существует (AttributeError) я думаю, что если бы я был вами, я сделаю это так:

class A(object):
    def __init__(self, *args, **kwargs):
       try:
           self._drivers = self.createDrivers(*args, **kwargs)
           select(self._drivers)
       except NotImplementedError:
           pass

    def createDrivers(self, *args, **kwargs):
        raise NotImplementedError("This class wasn't implemented")

class B(A):
    def createDrivers(self, *args, **kwargs):
        c1 = circle(sweep=270)[0]
        c2 = circle(sweep=180)[0]
        return c1, c2

class C(A):
    pass

Другой способ - заменить callable(self.createDrivers) на hasattr(self, 'createDrivers').

1 голос
/ 16 января 2011

Если вы хотите, чтобы createDrivers был необязательным, но при этом всегда присутствовал, лучшим будет не абстрактный метод, а его реализация в базовом классе в виде noop.

class A(object):
    def __init__(self, *args, **kwargs):
        self._drivers = self.createDrivers(*args, **kwargs)
        select(self._drivers)

    def createDrivers(self, *args, **kwargs):
        """This should be overridden by subclasses if they need custom drivers"""
        pass
1 голос
/ 16 января 2011

Я бы сделал это:

class A(object):
    def __init__(self, *args, **kwargs):
        self.createDrivers(*args, **kwargs)

    def createDrivers(self, *args, **kwargs):
        "Override"
        pass

class B(A):
    def createDrivers(self, *args, **kwargs):
        self._drivers = blabla
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...