2011-05-17 12 views
26

Digamos que tengoanulación de método de Python, ¿importa la firma?

class Super(): 
    def method1(): 
    pass 

class Sub(Super): 
    def method1(param1, param2, param3): 
     stuff 

Es esto correcto? ¿Las llamadas a method1 siempre irán a la subclase? Mi plan es tener 2 subclases cada uno reemplazar método1 con diferentes parámetros

Respuesta

1

En python, todos los métodos de clase son "virtuales" (en términos de C++). Así, en el caso de su código, si desea llamar method1() en la superclase, que tiene que ser:

class Super(): 
    def method1(self): 
     pass 

class Sub(Super): 
    def method1(self, param1, param2, param3): 
     super(Sub, self).method1() # a proxy object, see http://docs.python.org/library/functions.html#super 
     pass 

Y la firma del método es importante. No se puede llamar a un método como este:

sub = Sub() 
sub.method1() 
25

Python permitirá esto, pero si method1() está previsto para ser ejecutado desde código externo a continuación, es posible que desee volver a examinar esto, ya que viola LSP y así no lo hará siempre trabaje apropiadamente

+0

es la violación de la LSP en el hecho de que Sub.method1 toma 3 argumentos, mientras que Super.method1 toma ninguna haciéndolos de hecho diferentes interfaces? – Unode

+1

@Unode: Correcto. Esto podría resolverse haciendo que todos los argumentos del método de la subclase tengan valores predeterminados, pero luego entones cuáles serían los predeterminados. –

+2

Ya veo. Pero luego solo para aclarar. Si el método padre1 se definió como 'Super.method1 (param1 = None, param2 = None, param3 = None)' todavía violaría a LSP si en las subclases se define como 'Sub.method1 (param1, param2, param3)' right? Como los atributos son obligatorios en un caso pero no en el otro. Por lo tanto, a mi entender sin cambiar la interfaz de la subclase, la única forma de no violar LSP sería tener los parámetros sin valores predeterminados en el padre. ¿Estoy en lo correcto o sobreinterpretando el LSP? – Unode

-2

Sí. Las llamadas a "método1" siempre irán a la subclase. La firma del método en Python solo consiste en el nombre y no en la lista de argumentos.

+2

Falsa respuesta. La firma del método siempre importa, porque no hay sobrecarga de funciones como sucede con C/C++. –

+0

Lo que quiero decir es que Python no considera la lista de argumentos para decidir qué método llamar, ¡pero creo que tienes razón cuando lo miras desde _that_ angle! – Elektito

0

va a trabajar:

>>> class Foo(object): 
... def Bar(self): 
...  print 'Foo' 
... def Baz(self): 
...  self.Bar() 
... 
>>> class Foo2(Foo): 
... def Bar(self): 
...  print 'Foo2' 
... 
>>> foo = Foo() 
>>> foo.Baz() 
Foo 
>>> 
>>> foo2 = Foo2() 
>>> foo2.Baz() 
Foo2 

Sin embargo, esto no se recomienda generalmente. Eche un vistazo a la respuesta de S.Lott: Methods with the same name and different arguments are a code smell.

1

Se podría hacer algo como esto si es aceptable utilizar los argumentos por defecto:

>>> class Super(): 
... def method1(self): 
...  print("Super") 
... 
>>> class Sub(Super): 
... def method1(self, param1="X"): 
...  super(Sub, self).method1() 
...  print("Sub" + param1) 
... 
>>> sup = Super() 
>>> sub = Sub() 
>>> sup.method1() 
Super 
>>> sub.method1() 
Super 
SubX 
Cuestiones relacionadas