91 votes

Python : modification des méthodes et des attributs à l'exécution

Je souhaite créer une classe en Python à laquelle je peux ajouter et supprimer des attributs et des méthodes. Comment puis-je y parvenir ?

Oh, et s'il vous plaît ne demandez pas pourquoi.

132voto

Paolo Bergantino Points 199336

Cet exemple montre les différences entre l'ajout d'une méthode à une classe et à une instance.

>>> class Dog():
...     def __init__(self, name):
...             self.name = name
...
>>> puppy = Dog('Skip')
>>> spot = Dog('Spot')
>>> def talk(self):
...     print 'Hi, my name is ' + self.name
...
>>> Dog.talk = talk # add method to class
>>> puppy.talk()
Hi, my name is Skip
>>> spot.talk()
Hi, my name is Spot
>>> del Dog.talk # remove method from class
>>> puppy.talk() # won't work anymore
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: Dog instance has no attribute 'talk'
>>> import types
>>> f = types.MethodType(talk, puppy, Dog)
>>> puppy.talk = f # add method to specific instance
>>> puppy.talk()
Hi, my name is Skip
>>> spot.talk() # won't work, since we only modified puppy
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: Dog instance has no attribute 'talk'

48voto

Unknown Points 22789

Je souhaite créer une classe en Python à laquelle je peux ajouter et supprimer des attributs et des méthodes.

import types

class SpecialClass(object):
    @classmethod
    def removeVariable(cls, name):
        return delattr(cls, name)

    @classmethod
    def addMethod(cls, func):
        return setattr(cls, func.__name__, types.MethodType(func, cls))

def hello(self, n):
    print n

instance = SpecialClass()
SpecialClass.addMethod(hello)

>>> SpecialClass.hello(5)
5

>>> instance.hello(6)
6

>>> SpecialClass.removeVariable("hello")

>>> instance.hello(7)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'SpecialClass' object has no attribute 'hello'

>>> SpecialClass.hello(8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'SpecialClass' has no attribute 'hello'

31voto

Alex Martelli Points 330805

Une alternative intéressante à l'utilisation de types.MethodType dans :

>>> f = types.MethodType(talk, puppy, Dog)
>>> puppy.talk = f # add method to specific instance

serait d'exploiter le fait que les fonctions sont descripteurs :

>>> puppy.talk = talk.__get__(puppy, Dog)

8voto

Robert Rossney Points 43767

Je souhaite créer une classe en Python à laquelle je peux ajouter et supprimer des attributs et des méthodes. Comment puis-je y parvenir ?

Vous pouvez ajouter et supprimer des attributs et des méthodes à toute classe, et ils seront disponibles pour toutes les instances de la classe :

>>> def method1(self):
       pass

>>> def method1(self):
       print "method1"

>>> def method2(self):
       print "method2"

>>> class C():
       pass

>>> c = C()
>>> c.method()

Traceback (most recent call last):
  File "<pyshell#62>", line 1, in <module>
    c.method()
AttributeError: C instance has no attribute 'method'

>>> C.method = method1
>>> c.method()
    method1
>>> C.method = method2
>>> c.method()
    method2
>>> del C.method
>>> c.method()

Traceback (most recent call last):
  File "<pyshell#68>", line 1, in <module>
    c.method()
AttributeError: C instance has no attribute 'method'
>>> C.attribute = "foo"
>>> c.attribute
    'foo'
>>> c.attribute = "bar"
>>> c.attribute
    'bar'

5voto

Johan Lundberg Points 5835

Vous pouvez simplement assigner directement à la classe (soit en accédant au nom original de la classe, soit via __class__ ) :

class a : pass
ob=a()
ob.__class__.blah=lambda self,k: (3, self,k)
ob.blah(5)
ob2=a()
ob2.blah(7)

imprimera

(3, <__main__.a instance at 0x7f18e3c345f0>, 5)
(3, <__main__.a instance at 0x7f18e3c344d0>, 7)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X