6

W odniesieniu do odpowiedzi dla this question jest to "Użyj modułu abc Pythona, aby utworzyć klasy abstrakcyjne." (przez @alexvassel i akceptowane jako odpowiedź).Potrafi utworzyć instancję klasy Python, pomimo że jest to Abstrakt (używając abc).

Próbowałem sugestii, ale o dziwo, pomimo podążania za sugestiami, jak korzystać z drogi abc, to nie działa dla mnie. Stąd jestem delegowania go jako pytanie tutaj:

Oto mój kod Python:

from abc import ABCMeta, abstractmethod 

class Abstract(object): 
    __metaclass__ = ABCMeta 

    @abstractmethod 
    def foo(self): 
     print("tst") 

a = Abstract() 
a.foo() 

Kiedy wykonać tego modułu, tutaj jest wyjście na konsolę:

pydev debugger: starting (pid: 20388) 
tst 

w przeciwieństwie do tej zaakceptowanej odpowiedzi

>>> TypeError: Can not instantiate abstract class Abstract with abstract methods foo 

Co więc robię dobrze, czy źle? Dlaczego praca nie kończy się niepowodzeniem? Doceń wszelkie wgląd ekspertów w to.

+0

Byłem w stanie jednoznacznie odpowiedzieć na to pytanie? –

Odpowiedz

7

W Pythonie 3 używać metaclass argumentu podczas tworzenia klasy abstrakcyjnej Base:

from abc import ABCMeta, abstractmethod 

class Abstract(metaclass=ABCMeta): 

    @abstractmethod 
    def foo(self): 
     print("tst") 

a = Abstract() 
a.foo() 
+0

Rozumiem. To jest świetna informacja do poznania. Działa po tym, jak zmodyfikowałem definicję zgodnie z sugestią. Dzięki. – jark

4

W Pythonie 2, należy przypisać metaklasą wygląda następująco:

import abc 

class ABC(object): 

    __metaclass__ = abc.ABCMeta 

    @abc.abstractmethod 
    def foo(self): 
     return True 

a = ABC() 

co podnosi się TypeError

Traceback (most recent call last): 
    File "<pyshell#59>", line 1, in <module> 
    a = ABC() 
TypeError: Can't instantiate abstract class ABC with abstract methods foo 

Ale w Pythonie 3, przypisanie __metaclass__ jako atrybut nie działa (tak jak sobie tego życzysz, ale interpreter nie uważa go za błąd, po prostu normalny atrybut jak każdy inny, dlatego powyższy kod nie spowodowałby błędu). Metaclasses są teraz zdefiniowane jako nazwanego argumentu klasy:

import abc 

class ABC(metaclass=abc.ABCMeta): 

    @abc.abstractmethod 
    def foo(self): 
     return True 

a = ABC() 

podnosi TypeError:

Traceback (most recent call last): 
    File "main.py", line 11, in 
    a = ABC() 
TypeError: Can't instantiate abstract class ABC with abstract methods foo 
+0

Dziękuję za szczegółowe wyjaśnienie, dlaczego nie powoduje to błędu w Pythonie 2. Żałuję, że nie działa bez cichej pracy, ponieważ nie chciałem tego :( – jark

+0

@jark Ciekawe, że wybrałeś kod Victory, ponieważ jest nieprawidłowy dla Pythona 3 i właściwie nie pokazuje tego, czego szukałeś –

+0

Aaron Hall, dziękuję za twoją opinię Zgadzam się z odpowiedzią Victory, ponieważ to był pierwszy, który wszedł, a ja czytałem i próbowałem i działało tak jak się spodziewałem Nie wiem, dlaczego mówisz, że jest to "Invalid for Python 3"? Jeśli porównuję kod, który umieściłeś w swoim rozwiązaniu z tym, co opublikował Victory, obie używają dokładnie tej samej logiki. "importuj abc" (z kolei używając metody abc.abstract itp.) vs Zwycięstwo używając "z abc import ABCMeta, abstractmethod" i używając abstractmethod itp. Nic osobistego przeciwko tobie nie jest dla Victory, – jark