Dovrei usare metodi astratti in questo scenario Python?
-
11-10-2019 - |
Domanda
Non sono sicuro che il mio approccio è un buon design e spero che posso ottenere un suggerimento. Sto pensando da qualche parte lungo le linee di un metodo astratto, ma in questo caso voglio il metodo per essere facoltativo. Questo è il modo che sto facendo ora ...
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()
Nell'esempio di cui sopra, sto solo la creazione di 2 archi di cerchio in PyMEL per Maya, ma sono fermamente intenzionato a creare più sottoclassi che possono o non possono avere un metodo createDrivers a tutti! Quindi io voglio che sia facoltativo e mi chiedo se il mio approccio è be ', se il mio approccio potrebbe essere migliorato?
Soluzione
Hai ancora un problema, quando si sarà ereditare la classe B, e questo chiamerà A.__init__
e se non si implementa createDrivers
nella sottoclasse questa linea callable(self.createDrivers)
genera un errore come quello createDrivers
non esiste (AttributeError) penso che se fossi in te lo farò in questo modo:
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
Un altro modo è quello di sostituire callable(self.createDrivers)
da hasattr(self, 'createDrivers')
.
Altri suggerimenti
Se si desidera createDrivers essere facoltativo, ma ancora sempre lì, il migliore non è un metodo astratto, ma non applicarla nella classe base come 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
Vorrei fare questo:
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