Comment étendre une classe interne en python? Je voudrais ajouter une méthode à la classe str.
J'ai fait quelques recherches, mais tout ce que je trouve est des messages plus anciens, j'espère que quelqu'un sait quelque chose de plus récent.Extension de classes intégrées en python
Répondre
Juste sous-classe du type
>>> class X(str):
... def myMethod(self):
... return int(self)
...
>>> s=X("Hi Mom")
>>> s.lower()
'hi mom'
>>> s.myMethod()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in myMethod
ValueError: invalid literal for int() with base 10: 'Hi Mom'
>>> z=X("271828")
>>> z.lower()
'271828'
>>> z.myMethod()
271828
J'espérais que je n'aurais pas à sous-classe, mais après quelques recherches supplémentaires, je suis arrivé à la conclusion que ce n'est pas possible autrement, alors j'accepte cette réponse. – UnkwnTech
@Unkwntech: Impossible d'imaginer une meilleure façon que le sous-classement. Sérieusement. Tout ce que vous avez en tête (monkeypatching?) Ne semble jamais fonctionner aussi bien qu'une sous-classe claire, précise et évidente. –
@ S.Lott - Les classes ouvertes de Ruby et les méthodes d'extension C# me viennent à l'esprit. – orip
Une façon pourrait être d'utiliser le concept de « réouverture de classe » (native existant en Ruby) qui peut être mis en œuvre en Python à l'aide d'un décorateur de classe. Un exemple est donné dans cette page: http://www.ianbicking.org/blog/2007/08/opening-python-classes.html
Je cite:
Je pense avec des décorateurs de classe que vous pouvez faire:
@extend(SomeClassThatAlreadyExists)
class SomeClassThatAlreadyExists:
def some_method(self, blahblahblah):
stuff
Mis en œuvre comme ceci:
def extend(class_to_extend):
def decorator(extending_class):
class_to_extend.__dict__.update(extending_class.__dict__)
return class_to_extend
return decorator
En supposant que vous ne pouvez pas modifier les classes intégrées. Pour simuler une « classe réouverture » comme Ruby dans python3 où __dict__
est un objet mappingproxy et non objet dict:
def open(cls):
def update(extension):
for k,v in extension.__dict__.items():
if k != '__dict__':
setattr(cls,k,v)
return cls
return update
class A(object):
def hello(self):
print('Hello!')
A().hello() #=> Hello!
#reopen class A
@open(A)
class A(object):
def hello(self):
print('New hello!')
def bye(self):
print('Bye bye')
A().hello() #=> New hello!
A().bye() #=> Bye bye
Je pourrais aussi écrire une fonction décorateur « ouverte » ainsi:
def open(cls):
def update(extension):
namespace = dict(cls.__dict__)
namespace.update(dict(extension.__dict__))
return type(cls.__name__,cls.__bases__,namespace)
return update
possible duplicata de [Pouvez-vous des méthodes de patch singe sur les types de base en python?] (http://stackoverflow.com/questions/192649/can-you-monkey-patch-methods-on-core-types-in-python) – jfs
Voir aussi –
sanxiyn