2011-08-25 17 views
17

Przeczytałem docs Pythona o abstrakcyjnych klas bazowych:pyton @abstractmethod dekorator

Od here:

abc.abstractmethod(function) dekorator wskazujący metody abstrakcyjne.

Korzystanie z tego dekoratora wymaga, aby metaclass klasy był ABCMeta lub pochodził z niej klasa ABCMeta lub . Klasa, która ma metaklas pochodzący od ABCMeta , nie może być utworzona, chyba że wszystkie jej abstrakcyjne metody i właściwości zostaną nadpisane.

I here

Można zastosować @abstractmethod dekorator do metod, takich jak Draw() , które muszą być wdrożone; Python podniesie wyjątek dla klas , które nie definiują metody. Zauważ, że wyjątek jest tylko podniesiony, gdy faktycznie próbujesz utworzyć instancję podklasy bez tej metody.

Użyłem tego kodu, aby sprawdzić, czy na zewnątrz:

import abc 

class AbstractClass(object): 
    __metaclass__ = abc.ABCMeta 

    @abc.abstractmethod 
    def abstractMethod(self): 
    return 

class ConcreteClass(AbstractClass): 
    def __init__(self): 
    self.me = "me" 

c = ConcreteClass() 
c.abstractMethod() 

Kod idzie dobrze, więc ja nie rozumiem. Jeśli wpiszę: c.abstractMethod, otrzymam:

<bound method ConcreteClass.abstractMethod of <__main__.ConcreteClass object at 0x7f694da1c3d0>> 

Czego mi tu brakuje? ConcreteClassmusi zastosować metody abstrakcyjne, ale nie mam wyjątków.

+2

Który python? Zgłasza błąd dla mnie. Zawsze możesz też wywołać NotImplementedError zamiast używać 'abc'. –

+0

Dodaję komentarz do odpowiedzi mouad, link z 'python' został ustawiony jako domyślny na' python3'. Będę miał na uwadze podniesienie wyjątku, ponieważ pisanie przenośnego kodu z tymi zmianami na pythonie wydaje się być dalekie od mojej wiedzy Pythona. – Sebastian

Odpowiedz

25

Czy używasz python3 do uruchomienia tego kodu? jeśli tak, powinieneś wiedzieć, że deklarując metaclass w python 3 have changes powinieneś zrobić to tak:

import abc 

class AbstractClass(metaclass=abc.ABCMeta): 

    @abc.abstractmethod 
    def abstractMethod(self): 
     return 
+0

Dzięki, wydaje się to ogromną zmianą między wersjami (moja dystrybucja wskazywała 'python' na domyślną jako' python3'). Jak napisać to ze względu na kompatybilność wsteczną? Myślę, że to może być kolejne pytanie ... – Sebastian

+1

@Sebastian: 'python3' został zaprojektowany z mniejszą kompatybilnością wsteczną z jego poprzednikiem python2 (http://www.python.org/dev/peps/pep-3000/#compatibility-and -transition), ale aby rozwiązać zacofanie między wersjami, powinieneś użyć skryptu 2to3.py (http://docs.python.org/library/2to3.html). – mouad

+0

miło, przetestowałem to. Mogę dalej używać składni "__metaclass__" i używać tego skryptu do konwertowania na składnię 'python3'. Po prostu zrobił to, co napisałeś w tym przykładzie. Dzięki. – Sebastian