Как расширить класс в Python?

92

Как в Python можно расширить класс? Например, если у меня есть

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!"

Но это не работает ... Я ожидаю, что если я буду работать color_extended.py, то когда я создам цветной объект и использую getcolorфункцию, он вернет объект со строкой «расширенный!» в конце. Также он должен был получить инициализацию из импорта.

Предположим, что Python 3.1

Благодарность

омега
источник
2
Вы пробовали читать документацию? docs.python.org/2.7/tutorial/classes.html#inheritance
wRAR,
классы должны иметь первую букву с заглавной буквы («Цвет», а не «Цвет»);)
daveoncode
14
@wRAR Может быть, в 2013 году это разумный вопрос, но давайте будем честными - люди сначала обращаются к StackOverflow, так что это хороший вопрос для SO. Этот вопрос - первое попадание в Google для "класса расширения python", документация - третья.
TC Proctor

Ответы:

94

Использование:

import color

class Color(color.Color):
    ...

Если бы это было Python 2.x, вы также хотели бы получить color.Colorот того object, чтобы сделать это класс нового типа :

class Color(object):
    ...

В Python 3.x это не обязательно.

NPE
источник
31
Стоит отметить, что вы можете дать новому классу то же имя, что и старый: class color(color):определяет новый класс, который заменяет старый, но является производным от него. (Кажется, это именно то, что пытается сделать ОП.)
kindall
17
class extended_color(color):Обычно это плохие стандарты - class ExtendedColor(Color):должно быть для занятий. Просто
придирка
Вопрос нуба здесь: почему вы не использовали __init__?
Mentalist
0

Другой способ расширения (в частности, добавления новых методов, а не изменения существующих) классов, даже встроенных, заключается в использовании препроцессора, который добавляет возможность расширяться за пределы / за пределы самого Python, преобразовывая расширение в нормальный синтаксис Python до того, как Python действительно увидит его.

Я сделал это, например, для расширения str()класса Python 2 . str()является особенно интересной целью из-за неявной связи с цитируемыми данными, такими как 'this'и 'that'.

Вот некоторый расширяющийся код, где единственным добавленным синтаксисом, отличным от Python, является extend:testDottedQuadбит:

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

После чего я могу написать в коде, подаваемом в препроцессор:

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'

Препроцессор съедает это, выплевывает обычный Python без обезьяньего исправления, а Python делает то, что я намеревался делать.

Подобно тому, как препроцессор ac добавляет функциональность к c, препроцессор Python также может добавлять функциональность к Python.

Моя реализация препроцессора слишком велика для ответа на вопрос о переполнении стека, но для тех, кому это может быть интересно, она находится здесь, на GitHub.

Фингырз
источник