Znam metody wirtualne z PHP lub Java.Jak wdrażać metody wirtualne w Pythonie?
Jak można je wdrożyć w Pythonie?
Czy muszę zdefiniować pustą metodę w klasie abstrakcji i przesłonić ją?
Znam metody wirtualne z PHP lub Java.Jak wdrażać metody wirtualne w Pythonie?
Jak można je wdrożyć w Pythonie?
Czy muszę zdefiniować pustą metodę w klasie abstrakcji i przesłonić ją?
Oczywiście, i nie trzeba nawet definiować metody w klasie bazowej. W Pythonie metody są lepsze od wirtualnych - są całkowicie dynamiczne, ponieważ pisanie w języku Python to pisanie na kaczce.
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
i Dog
w Pythonie nie trzeba nawet czerpać ze wspólnej klasy bazowej, aby umożliwić to zachowanie - można zdobyć za darmo. To powiedziawszy, niektórzy programiści wolą definiować hierarchie klas w bardziej sztywny sposób, aby udokumentować to lepiej i narzucać pewną ścisłość pisania. Jest to również możliwe - patrz na przykład abc
standard module.
Metody Pythona są zawsze wirtualne.
Faktycznie, w wersji 2.6 Pythona zapewnia sth nazywa streszczenie baza klas i można jawnie ustawić metod wirtualnych tak:
from abc import ABCMeta
from abc import abstractmethod
...
class C:
__metaclass__ = ABCMeta
@abstractmethod
def my_abstract_method(self, ...):
To działa bardzo dobrze, pod warunkiem, że klasa nie dziedziczą z klas, które już korzystają z metaclasses .
metody Python zawsze są wirtualne
jak Ignacio powiedział jeszcze Jakoś klasa dziedziczenia może być lepszym podejściem do wdrożenia, co chcesz.
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
Wyniki powinny być:
I am an unknown animal
I am a dog named Rover
Rover has 4 legs
NotImplementedError
Wyjątkiem jest zalecany w celu podniesienia na „czystych metod wirtualnych” z „WWW” klas bazowych, które nie wdrażają metodę.
Jak powiedzieli inni, jest to głównie konwencja dokumentacji i nie jest wymagana, ale w ten sposób uzyskuje się bardziej znaczący wyjątek niż błąd brakującego atrybutu.
https://docs.python.org/3.5/library/exceptions.html#NotImplementedError mówi:
Wyjątek pochodzi z
RuntimeError
. W zdefiniowanych przez użytkownika klasach bazowych, metody abstrakcyjne powinny podnosić ten wyjątek, gdy wymagają klas pochodnych, aby zastąpić metodę.
Np.:
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()
daje:
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
pokrewne: Is it possible to make abstract classes in python?
metody Python zawsze są wirtualne.
... pod warunkiem, że nie są prywatne! Szkoda dla gościa w C++.
'cat.say()' powinno być 'another_pet.say()' – dusan
@dusan: dziękuję. naprawiony. –
+1 dla przykładu. W jakim języku psy mówią "hau" nawiasem mówiąc? – JeremyP