2011-01-17 15 views

Odpowiedz

71

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.

+0

'cat.say()' powinno być 'another_pet.say()' – dusan

+0

@dusan: dziękuję. naprawiony. –

+9

+1 dla przykładu. W jakim języku psy mówią "hau" nawiasem mówiąc? – JeremyP

40

Metody Pythona są zawsze wirtualne.

16

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 .

źródło: http://docs.python.org/2/library/abc.html

7

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 
13

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?

2

metody Python zawsze są wirtualne.

... pod warunkiem, że nie są prywatne! Szkoda dla gościa w C++.

Powiązane problemy