Si bien soy consciente de que no puede hacer referencia self
directamente en un decorador, me preguntaba si es una mala práctica solucionarlo tirando de args[0]
. Mi corazonada es que así es, pero quiero estar seguro.¿Es una mala práctica usar uno mismo en decoradores?
Para ser más específicos, estoy trabajando en una API para un servicio web. Aproximadamente la mitad de los comandos requieren que se pase un token que luego se puede usar para deshacerlo. Lo que me gustaría es convertir ese token en un parámetro opcional y si no se proporciona ninguno, generar uno. Generar un token requiere realizar una llamada autenticada al servidor, que necesita datos del objeto.
Aunque sé que podría hacerlo:
def some_command(self, ..., undo_token = None):
if undo_token = None:
undo_token = self.get_undo_token()
...
return fnord
Siento que podría haber una forma mejor que tener el mismo código en una docena de métodos. Mi idea era escribir un decorador:
@decorator
def undoable(fn, *args, **kwargs):
if 'undo_token' not in kwargs:
kwargs['undo_token'] = args[0].get_undo_token()
return (fn(*args, **kwargs), kwargs['undo_token'])
Así que se puede escribir de forma más limpia
@undoable
def some_command(self, ...):
...
return foo
@undoable
def some_other_command(self, ...):
...
return bar
Estoy dando a mí mismo para problemas en el momento?
+1 para usar el patrón de decorador para implementar "deshacer". –
No hay nada de malo en que un decorador tenga requisitos sobre los parámetros de la función que se está decorando; solo asegúrate de que esté documentado. –