Soll ich in diesem Python Szenario mit abstrakten Methoden sein?
-
11-10-2019 - |
Frage
Ich bin nicht sicher, ob mein Ansatz ist ein gutes Design und ich hoffe, ich einen Tipp bekommen. Ich denke, irgendwo entlang der Linien eines abstrakten Methode, aber in diesem Fall möchte ich die Methode optional sein. Dies ist, wie ich tue es jetzt ...
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()
Im obigen Beispiel, Ich schaffe nur 2 Kreisbögen in PyMEL für Maya, aber ich beabsichtige, sich ganz auf mehr Unterklassen zu schaffen, die keine createDrivers Methode überhaupt haben können oder nicht! Also habe ich es optional sein will und ich frage mich, ob mein Ansatz ist-gut, wenn mein Ansatz verbessert werden könnte?
Lösung
Sie haben immer noch ein Problem, wenn Sie Ihre Klasse B erben werden, und dies wird A.__init__
anrufen und wenn Sie nicht createDrivers
implementieren in der Unterklasse dieser Linie callable(self.createDrivers)
einen Fehler aus, als dass createDrivers
nicht existiert (Attribute) ich denke, wenn ich Sie wäre ich es wie so tun:
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
Eine andere Möglichkeit ist callable(self.createDrivers)
durch hasattr(self, 'createDrivers')
zu ersetzen.
Andere Tipps
Wenn Sie createDrivers optional sein wollen, aber noch immer, das Beste ist, nicht eine abstrakte Methode, sondern implementieren es in der Basisklasse als 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
Ich würde dies tun:
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