Comment étendre une classe en python?

92

En python, comment étendre une classe? Par exemple si j'ai

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

Mais cela ne fonctionne pas ... Je m'attends à ce que si je travaille dans color_extended.py, alors quand je crée un objet de couleur et utilise la getcolorfonction alors il retournera l'objet avec la chaîne "étendu!" à la fin. Il devrait également avoir obtenu l'initialisation de l'importation.

Supposons que python 3.1

Merci

oméga
la source
2
Avez-vous essayé de lire la documentation? docs.python.org/2.7/tutorial/classes.html#inheritance
wRAR
les classes doivent avoir la première lettre en majuscule ("Color" et non "color");)
daveoncode
14
@wRAR Peut-être qu'en 2013, c'est une question raisonnable, mais soyons honnêtes - les gens se tournent d'abord vers StackOverflow, c'est donc une bonne question à poser sur SO. Cette question est le premier hit google pour "python extend class", la documentation est la troisième.
TC Proctor

Réponses:

94

Utilisation:

import color

class Color(color.Color):
    ...

S'il s'agissait de Python 2.x, vous voudriez également dériver color.Colorde object, pour en faire une classe de style nouveau :

class Color(object):
    ...

Ce n'est pas nécessaire dans Python 3.x.

NPE
la source
31
Il est à noter que vous pouvez donner à la nouvelle classe le même nom que l'ancienne: class color(color):définit une nouvelle classe qui remplace l'ancienne, mais qui en est dérivée. (Cela semble être ce que l'OP essaie de faire.)
kindall
17
class extended_color(color):est généralement de mauvaises normes - class ExtendedColor(Color):devrait être pour les classes. Juste un
nitpick
Noob question ici: pourquoi n'avez-vous pas utilisé __init__?
Mentalist
0

Une autre façon d'étendre (ce qui signifie spécifiquement, d'ajouter de nouvelles méthodes, et non de changer celles existantes) des classes, même intégrées, consiste à utiliser un préprocesseur qui ajoute la possibilité d'étendre hors / au-dessus de la portée de Python lui-même, en convertissant l'extension en la syntaxe normale de Python avant que Python ne puisse la voir.

J'ai fait cela pour étendre la str()classe de Python 2 , par exemple. str()est une cible particulièrement intéressante en raison du lien implicite avec des données citées telles que 'this'et 'that'.

Voici un code d'extension, où la seule syntaxe non-Python ajoutée est le 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

Après quoi je peux écrire dans le code fourni au préprocesseur:

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'

Le préprocesseur mange ça, crache du Python normal sans monkeypatching, et Python fait ce que je voulais qu'il fasse.

Tout comme le préprocesseur ac ajoute des fonctionnalités à c, un préprocesseur Python peut également ajouter des fonctionnalités à Python.

L'implémentation de mon préprocesseur est trop volumineuse pour une réponse de débordement de pile, mais pour ceux qui pourraient être intéressés, elle est ici sur GitHub.

fyngyrz
la source