2010-01-29 6 views
2

Je souhaite modifier toutes les classes en Python. Par exemple str et int et d'autres comme Person (objet).Modification d'une classe Python

Je voudrais leur ajouter un attribut et changer le fonctionnement de leurs méthodes.

Quelle est la meilleure approche pour cela? Métaclasses?

+2

Quel est le cas d'utilisation? –

+0

Implémentation d'un mode de corruption pour Python. –

+2

Vous devrez également être en mesure de ré-implémenter tous les opérateurs dans la langue. Je ne pense pas que tu vas pouvoir faire ce que tu veux. –

Répondre

0

Vous ne pouvez pas éditer la classe directement comme avec l'attribut prototype javascript, il est préférable de les sous-classer. Cela vous permet d'ajouter la fonctionnalité que vous voulez et ne forcez pas à l'utiliser partout.

+0

Ok, comment puis-je faire cela par programmation? Je voudrais appliquer cette modification à beaucoup de classes. Je ne veux pas tous les étendre à la main. –

+0

Vous pouvez utiliser un décorateur de classe qui renvoie une version modifiée pour la classe. Ensuite, il suffit d'ajouter "@yourdecorator" en haut de chaque classe qui devrait être modifiée. – AndiDog

1

Les classes intégrées ne peuvent pas être modifiées, mais vous pouvez "masquer" une classe intégrée (ou toute autre, bien sûr) par un même nom.

Par exemple, supposons que le changement est d'ajouter un groupe de classes un nouvel attribut « foobar », dont la valeur initiale est 23, et à chaque exemple de ces classes un nouvel attribut « murf », dont la valeur initiale est 45. est ici une façon:

def changedclass(cls): 
    def __init__(self, *a, **k): 
    cls.__init__(self, *a, **k) 
    self.murf = 45 
    return type(cls.__name__, (cls,), {'foobar': 23, '__init__': __init__}) 

def changemany(changed, classes_by_module): 
    for module, classnames in classes_by_module.iteritems(): 
    for name in classnames: 
     cls = getattr(module, name) 
     subcls = changed(cls) 
     setattr(module, name, subcls) 

import __builtin__ 
import mymod 
changemany(changedclass, {__builtin__: ('int', 'str'), mymod: ('Person',)}) 

Notez que les littéraux nus comme « ciao » et 23 appartiendront toujours aux vrais cours - il n'y a pas moyen de changer cela; vous aurez besoin d'utiliser str('ciao') et int(23) pour utiliser les classes "fausses".

+0

Comment pourriez-vous surcharger la méthode \ _ \ _ add__ pour la classe modifiée? –

+0

Exactement la même manière. –

3

Bien que vous puissiez le faire pour les classes définies en code python (cela ne fonctionnera pas pour les classes internes) en réaffectant leurs attributs, ne le faites pas. Juste sous-classe et utilisez la sous-classe, ou écrire des fonctions qui prennent une instance de la classe comme argument au lieu d'ajouter vos propres méthodes. Faire ce que vous avez à l'esprit conduit à un code maladroit et fragile, surtout si vous finissez par utiliser simultanément plusieurs bibliothèques qui essaient de faire cela aux mêmes classes.

Y at-il un problème réel que vous essayez de résoudre de cette façon?

0

sous-classe:


class int(int): 
    def foo(self): 
    print "foo" 

int(2).foo()