2011-07-28 11 views
7

Estoy tratando de extender un método con un solo argumento de palabras clave sin dejar de ser imparcial con el resto de la firma del método; Solo quiero pasar eso. Intento de 0:Python: ¿Qué es un modismo elegante para extender el método con uno o más argumentos de palabra clave?

class SomeSuperclass(object): 
    pass # in reality: some implementation for some_method 

class SomeClass(SomeSuperclass): 
    def some_method(self, my_kwarg=42, *args, **kwargs): 
     super(SomeClass, self).some_method(*args, **kwargs) 
     do_something_interesting_with(my_kwarg) 

SomeClass().some_method('arg 0', 'arg 1', some_kwargs=5, my_kwarg=8) 

esto no funciona:

Traceback (most recent call last): 
    File "test.py", line 9, in <module> 
    SomeClass().some_method('arg 0', 'arg 1', some_kwargs=5, my_kwarg=8) 
TypeError: some_method() got multiple values for keyword argument 'my_kwarg' 

entiendo perfectamente por qué el anterior no funciona, pero estoy buscando una buena manera de hacer que funcione. Este es mi actual (feo) solución:

class SomeClass(SomeSuperclass): 
    def some_method(self, *args, **kwargs): 
     my_kwarg = kwargs.get('my_kwarg', 42) 
     if 'my_kwarg' in kwargs: 
      del kwargs['my_kwarg'] 
     super(SomeClass, self).some_method(*args, **kwargs) 
     do_something_interesting_with(my_kwarg) 

Eso es 3 líneas de costra por kwarg ...

Respuesta

6

que haría uso de dict.pop(), así:

class SomeSuperclass(object): 
    def some_method(self, *args, **kwargs): 
    print 'SomeSuperclass: args=%s kwargs=%s' % (args, kwargs) 

class SomeClass(SomeSuperclass): 
    def some_method(self, *args, **kwargs): 
    my_kwarg = kwargs.pop('my_kwarg', 42) # 42 is the default 
    print 'SomeClass: my_kwarg=%s' % my_kwarg 
    super(SomeClass, self).some_method(*args, **kwargs) 

SomeClass().some_method('arg 0', 'arg 1', some_kwargs=5, my_kwarg=8) 
SomeClass().some_method('arg 0', 'arg 1', some_kwargs=5) 

Cuando se ejecuta, este imprime:

SomeClass: my_kwarg=8 
SomeSuperclass: args=('arg 0', 'arg 1') kwargs={'some_kwargs': 5} 
SomeClass: my_kwarg=42 
SomeSuperclass: args=('arg 0', 'arg 1') kwargs={'some_kwargs': 5} 
1

puede utilizar {}.pop() para convertir sus 3 líneas de costra en 1:

my_kwarg = kwargs.pop('my_kwarg', 42) 
+0

Creo que esto también funciona: my_kwarg = kwargs.pop ('my_kwarg', 42) – FredL

Cuestiones relacionadas