Como estender uma classe em python?

90

Em python, como você pode estender uma classe? Por exemplo, se eu tiver

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

Mas isso não funciona ... Espero que se eu trabalhar em color_extended.py, quando eu fizer um objeto de cor e usar a getcolorfunção, ele retornará o objeto com a string "extendido!" No final. Também deve ter obtido o init da importação.

Suponha que o python 3.1

obrigado

ómega
fonte
2
Você tentou ler a documentação? docs.python.org/2.7/tutorial/classes.html#inheritance
wRAR
as classes devem ter a primeira letra maiúscula ("Color" e não "color");)
daveoncode
12
@wRAR Talvez em 2013 esta seja uma pergunta razoável, mas vamos ser honestos - as pessoas recorrem primeiro ao StackOverflow, então esta é uma boa pergunta para se ter no SO. Esta pergunta é o primeiro hit do Google para "classe extender python", a documentação é a terceira.
TC Proctor

Respostas:

92

Usar:

import color

class Color(color.Color):
    ...

Se isso fosse Python 2.x, você também gostaria de derivar color.Colorde object, para torná-lo uma classe new-style :

class Color(object):
    ...

Isso não é necessário no Python 3.x.

NPE
fonte
31
É importante notar que você pode dar à nova classe o mesmo nome da antiga: class color(color):define uma nova classe que substitui a antiga, mas que é derivada dela. (Isso parece ser o que o OP está tentando fazer.)
Kindall
16
class extended_color(color):normalmente são padrões ruins - class ExtendedColor(Color):deveriam ser para as aulas. Apenas um
detalhe
0

Outra maneira de estender (especificamente significando, adicionar novos métodos, não alterar os existentes) classes, mesmo as integradas, é usar um pré-processador que adiciona a capacidade de estender para fora / acima do escopo do próprio Python, convertendo a extensão para sintaxe normal do Python antes que o Python realmente consiga vê-la.

Fiz isso para estender a str()classe do Python 2 , por exemplo. str()é um alvo particularmente interessante por causa da ligação implícita aos dados citados como 'this'e 'that'.

Aqui está um código de extensão, em que a única sintaxe não Python adicionada é o 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

Depois disso, posso escrever no código fornecido ao pré-processador:

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'

O pré-processador come isso, cospe o Python normal sem o monkeypatching, e o Python faz o que eu pretendia fazer.

Assim como um pré-processador ac adiciona funcionalidade a c, também um pré-processador Python pode adicionar funcionalidade ao Python.

Minha implementação de pré-processador é muito grande para uma resposta de estouro de pilha, mas para aqueles que possam estar interessados, ela está aqui no GitHub.

Fyngyrz
fonte