Python Método de sustitución, no de la firma de la materia?

Digamos que tengo

class Super():
  def method1():
    pass

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

Es esto correcto? Se llama a method1 siempre ir a la sub clase? Mi plan es tener 2 sub clases de cada reemplazar method1 con diferentes parámetros

InformationsquelleAutor asdasasdsa | 2011-05-17

6 Kommentare

  1. 35

    Python permiten esto, pero si method1() está destinado a ser ejecutado a partir de código externo, entonces usted puede desear reconsiderar esto, ya que se viola LSP y por tanto no siempre funciona correctamente.

    • Es la violación de LSP en el hecho de que los Sub.method1 tarda de 3 argumentos, mientras que Super.method1 toma nada lo que la convierte en interfaces diferentes?
    • Correcto. Esto podría ser resuelto por tener los argumentos del método de la subclase, todos tienen valores por defecto, pero luego te metes en el cual por defecto sería apropiado.
    • Lo que yo veo. Pero, a continuación, sólo para aclarar. Si el padre method1 se define como Super.method1(param1=None, param2=None, param3=None) sería violar LSP si en subclases se define como Sub.method1(param1, param2, param3) derecho? Como atributos son obligatorios en un caso pero no en el otro. Por lo tanto, a mi entender, sin cambiar la subclase de la interfaz, el único modo de no violar LSP sería tener los parámetros sin valores por defecto en el padre. Estoy en lo cierto, sobre este o sobre-interpretación de la LSP?
    • También correcta. Tener el contrato se vuelven menos restrictiva en la subclase viola LSP.
  2. 16

    En Python, los métodos son sólo los pares clave-valor en el diccionario adjunta a la clase. Cuando se va a derivar una clase a partir de una clase base, básicamente está diciendo que el nombre del método se veía en primera clase derivada de diccionario y, a continuación, en la clase base diccionario. Con el fin de «anular» un método, usted simplemente volver a declarar el método en la clase derivada.

    Así, lo que si se cambia la firma del método reemplazado en la clase derivada? Todo funciona correctamente si la llamada está en la derivada de la instancia, pero si usted hace la llamada a la base de instancia, se producirá un error debido a que la base de la clase utiliza una firma diferente para el mismo nombre de método.

    Sin embargo, hay frecuentes casos en los que desee método de la clase derivada tiene adicionales parámetros y desea llamada de método de trabajo sin error en base de bien. Este es el llamado «principio de sustitución de Liskov» (o LSP) que garantiza que si la persona cambia de base de derivados de la instancia o viceversa, que no tiene que reformar su código. Para hacer esto en Python, usted necesita para diseñar su clase base con la siguiente técnica:

    class Base:
        # simply allow additional args in base class
        def hello(self, name, *args, **kwargs):
            print("Hello", name)
    
    class Derived(Base):
          # derived class also has unused optional args so people can
          # derive new class from this class as well while maintaining LSP
          def hello(self, name, age=None, *args, **kwargs):
              super(Derived, self).hello(name, age, *args, **kwargs) 
              print('Your age is ', age)
    
    b = Base()
    d = Derived()
    
    b.hello('Alice')        # works on base, without additional params
    b.hello('Bob', age=24)  # works on base, with additional params
    d.hello('Rick')         # works on derived, without additional params
    d.hello('John', age=30) # works on derived, with additional params

    Por encima de la voluntad de impresión:

     Hola Alicia 
    Hola Bob 
    Hola Rick 
    Su edad es de Ninguno 
    Hola Juan 
    Su edad es de 30 
    

    .
    Jugar con este código

  3. 1

    En python, todos los métodos de la clase son «virtuales» (en términos de C++). Así, en el caso de su código, si quieres llamar a method1() en super clase, 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 no importa. Usted no puede llamar a un método como este:

    sub = Sub()
    sub.method1() 
  4. 1

    Se podría hacer algo como esto si está bien usar predeterminado argumentos:

    >>> 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
  5. -2

    Sí. Las llamadas a «method1» siempre va a ir a la subclase. Firma del método en Python sólo consisten en el nombre y no la lista de argumentos.

    • Respuesta falsa. Firma del método siempre importa, porque no hay sobrecarga de funciones como ocurre en C/C++.
    • Lo que quiero decir, es Python no considerar la lista de argumentos para decidir qué método de llamar, pero supongo que tienes razón cuando se mira desde que ángulo!

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea