python3 method create python virtual-method

method - python interface



¿Cómo implementar métodos virtuales en Python? (6)

Conozco los métodos virtuales de PHP o Java.

¿Cómo se pueden implementar en Python?

¿O debo definir un método vacío en una clase abstracta y anularlo?


Los métodos de Python son siempre virtuales

como Ignacio dijo todavía. De alguna manera, la herencia de la clase puede ser un mejor enfoque para implementar lo que quieres.

class Animal: def __init__(self,name,legs): self.name = name self.legs = legs def getLegs(self): return "{0} has {1} legs".format(self.name, self.legs) def says(self): return "I am an unknown animal" class Dog(Animal): # <Dog inherits from Animal here (all methods as well) def says(self): # <Called instead of Animal says method return "I am a dog named {0}".format(self.name) def somethingOnlyADogCanDo(self): return "be loyal" formless = Animal("Animal", 0) rover = Dog("Rover", 4) #<calls initialization method from animal print(formless.says()) # <calls animal say method print(rover.says()) #<calls Dog says method print(rover.getLegs()) #<calls getLegs method from animal class

Los resultados deberían ser:

I am an unknown animal I am a dog named Rover Rover has 4 legs


Los métodos de Python son siempre virtuales.

... ¡siempre que no sean privados! Muy mal para un chico de C ++.


Claro, y ni siquiera tiene que definir un método en la clase base. En Python, los métodos son mejores que virtuales, son completamente dinámicos, ya que el tipado en Python es tipado de pato .

class Dog: def say(self): print "hau" class Cat: def say(self): print "meow" pet = Dog() pet.say() # prints "hau" another_pet = Cat() another_pet.say() # prints "meow" my_pets = [pet, another_pet] for a_pet in my_pets: a_pet.say()

Cat y Dog en Python ni siquiera tienen que derivar de una clase base común para permitir este comportamiento: lo obtienes de forma gratuita. Dicho esto, algunos programadores prefieren definir sus jerarquías de clase de una manera más rígida para documentarlo mejor e imponer cierta rigurosidad de tipeo. Esto también es posible; consulte, por ejemplo, el módulo estándar abc .


En realidad, en la versión 2.6, python proporciona algo llamado clases base abstractas y puedes establecer explícitamente métodos virtuales como este:

from abc import ABCMeta from abc import abstractmethod ... class C: __metaclass__ = ABCMeta @abstractmethod def my_abstract_method(self, ...):

Funciona muy bien, siempre que la clase no herede de las clases que ya usan metaclases.

fuente: http://docs.python.org/2/library/abc.html


Los métodos de Python son siempre virtuales.


NotImplementedError

Esta es la excepción recomendada para plantear sobre "métodos virtuales puros" de clases base "abstractas" que no implementan un método.

Como otros dijeron, esta es principalmente una convención de documentación y no es necesaria, pero de esta manera se obtiene una excepción más significativa que la de un error de atributo faltante.

https://docs.python.org/3.5/library/exceptions.html#NotImplementedError dice:

Esta excepción se deriva de RuntimeError . En las clases base definidas por el usuario, los métodos abstractos deberían plantear esta excepción cuando requieren clases derivadas para anular el método.

P.ej:

class Base(object): def virtualMethod(self): raise NotImplementedError() def usesVirtualMethod(self): return self.virtualMethod() + 1 class Derived(Base): def virtualMethod(self): return 1 print Derived().usesVirtualMethod() Base().usesVirtualMethod()

da:

2 Traceback (most recent call last): File "./a.py", line 13, in <module> Base().usesVirtualMethod() File "./a.py", line 6, in usesVirtualMethod return self.virtualMethod() + 1 File "./a.py", line 4, in virtualMethod raise NotImplementedError() NotImplementedError

Relacionado: ¿Es posible crear clases abstractas en Python?