Jak rozszerzyć klasę w Pythonie?


92

W Pythonie, jak możesz rozszerzyć klasę? Na przykład, jeśli mam

color.py

class Color:
    def __init__(self, color):
        self.color = color
    def getcolor(self):
        return self.color

color_extended.py

import Color

class Color:
    def getcolor(self):
        return self.color + " extended!"

Ale to nie działa ... Spodziewam się tego, jeśli będę pracować color_extended.py , to kiedy utworzę obiekt koloru i użyję getcolorfunkcji, zwróci obiekt z ciągiem "rozszerzony!" na końcu. Powinien również pobrać init z importu.

Załóżmy, że Python 3.1

Dzięki


2
Czy próbowałeś przeczytać dokumentację? docs.python.org/2.7/tutorial/classes.html#inheritance
wRAR

klasy powinny mieć wielką literę ("Kolor" nie "kolor");)
daveoncode

14
@wRAR Może w 2013 roku to rozsądne pytanie, ale bądźmy szczerzy - ludzie zwracają się najpierw do StackOverflow, więc to jest dobre pytanie na SO. To pytanie jest pierwszym trafieniem Google dotyczącym "klasy rozszerzonej pythona", dokumentacja jest trzecia.
TC Proctor,

Odpowiedzi:


94

Posługiwać się:

import color

class Color(color.Color):
    ...

Gdyby to był Python 2.x, chciałbyś również wyprowadzić color.Colorz niego object, aby uczynić go klasą w nowym stylu :

class Color(object):
    ...

Nie jest to konieczne w Pythonie 3.x.


31
Warto zauważyć, że możesz nadać nowej klasie taką samą nazwę jak stara: class color(color):definiuje nową klasę, która zastępuje starą, ale jest od niej pochodną. (Wydaje się, że to właśnie próbuje zrobić OP.)
kindall

17
class extended_color(color):to zwykle złe standardy - class ExtendedColor(Color):powinno być na zajęciach. Tylko
czubek

Noob pytanie tutaj: dlaczego nie użyłeś __init__?
Mentalist

0

Innym sposobem na rozszerzenie (w szczególności dodanie nowych metod, a nie zmianę istniejących) klas, nawet wbudowanych, jest użycie preprocesora, który dodaje możliwość rozszerzenia poza zakres samego Pythona, konwertując rozszerzenie normalna składnia Pythona, zanim Python faktycznie ją zobaczy.

Zrobiłem to na przykład, aby rozszerzyć str()klasę Pythona 2 . str()jest szczególnie interesującym celem ze względu na niejawne powiązanie z cytowanymi danymi, takimi jak 'this'i 'that'.

Oto fragment kodu rozszerzającego, w którym jedyną dodaną składnią inną niż Python jest extend:testDottedQuadbit:

extend:testDottedQuad
def testDottedQuad(strObject):
    if not isinstance(strObject, basestring): return False
    listStrings = strObject.split('.')
    if len(listStrings) != 4: return False
    for strNum in listStrings:
        try:    val = int(strNum)
        except: return False
        if val < 0: return False
        if val > 255: return False
    return True

Po czym mogę napisać w kodzie podanym do preprocesora:

if '192.168.1.100'.testDottedQuad():
    doSomething()

dq = '216.126.621.5'
if not dq.testDottedQuad():
    throwWarning();

dqt = ''.join(['127','.','0','.','0','.','1']).testDottedQuad()
if dqt:
    print 'well, that was fun'

Preprocesor to zjada, wypluwa normalny Python bez monkeypatchingu, a Python robi to, co zamierzałem.

Tak jak preprocesor ac dodaje funkcjonalność do c, tak preprocesor Pythona może dodawać funkcje do Pythona.

Moja implementacja preprocesora jest zbyt duża, aby odpowiedzieć na przepełnienie stosu, ale dla tych, którzy mogą być zainteresowani, jest tutaj na GitHub.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.