¿Debo estar usando métodos abstractos en este escenario Python?
-
11-10-2019 - |
Pregunta
No estoy seguro de que mi enfoque es el buen diseño y espero que puedo conseguir una propina. Estoy pensando en algún lugar a lo largo de las líneas de un método abstracto, pero en este caso quiero que el método sea opcional. Así es como lo estoy haciendo ahora ...
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()
En el ejemplo anterior, sólo estoy creando 2 arcos de círculo en PyMEL para Maya, pero tengo la intención de crear más subclases que pueden o no pueden tener un método createDrivers en absoluto! Así que quiero que sea opcional y me pregunto si mi enfoque es bueno, si mi enfoque podría ser mejorado?
Solución
Usted todavía tiene un problema, cuando va a heredar la clase B, y esto va a llamar A.__init__
y si no se implementa createDrivers
en la subclase de esta línea callable(self.createDrivers)
generará un error como que no existe createDrivers
(AttributeError) creo que si yo fuera tú lo haré de esta manera:
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
Otra forma es reemplazar callable(self.createDrivers)
por hasattr(self, 'createDrivers')
.
Otros consejos
Si desea createDrivers a ser opcional, pero todavía está siempre allí, lo mejor no es un método abstracto, pero no ponerlo en práctica en la clase base como 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
Me gustaría hacer esto:
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