60 votes

Objet de classe vide en Python

J'enseigne un cours Python sur la programmation orientée objet et, alors que je m'entraîne à expliquer les classes, j'ai vu une définition de classe vide :

class Employee:
    pass

L'exemple poursuit en définissant un nom et d'autres attributs pour un objet de cette classe :

john = Employee()
john.full_name = "john doe"

Intéressant !

Je me demande s'il existe un moyen de définir dynamiquement une fonction pour une instance d'une classe comme celle-ci ? quelque chose comme.. :

john.greet() = print 'Hello, World!'

Cela ne fonctionne pas dans mon interpréteur Python, mais existe-t-il un autre moyen de le faire ?

1 votes

Possible ? Oui. Une bonne idée ? Rarement (en dehors d'une certaine métaprogrammation, bien sûr).

4 votes

La définition de classe vide la plus courte que j'ai vue est celle de gossamer-threads.com/lists/python/python/832915#832915 : Employee=type('Employee',(),{}) et ensuite john=Employee() etc.

48voto

katrielalex Points 40655

Une classe est plus ou moins une enveloppe fantaisiste pour une dict d'attributs aux objets. Lorsque vous instanciez une classe, vous pouvez lui attribuer des attributs, qui seront stockés dans le fichier foo.__dict__ ; de même, vous pouvez regarder dans foo.__dict__ pour tous les attributs que vous avez déjà écrits.

Cela signifie que vous pouvez faire des choses dynamiques intéressantes comme :

class Employee: pass
def foo(self): pass
Employee.foo = foo

ainsi que l'assignation à une instance particulière. (EDIT : ajout de self paramètre)

8 votes

Votre exemple ne fonctionnera pas comme prévu : john.foo() soulèvera un TypeError parce qu'il n'y a pas de self paramètre . Putting a function on a class turns it to a method, so it needs to take a self . On the other hand, if you assign a function to a instance, it remains a function and has no access to the instance self`, ce qui n'est généralement pas utile.

0 votes

@Jochen : vous avez bien sûr raison. Merci ! Pour l'OP : cela vous aidera probablement de comprendre ce qui n'allait pas et pourquoi cela le résout !

0 votes

@Jochen, merci d'apporter un peu de couleur à cette question. Quelle est l'importance/l'utilité de l'accès à un système de gestion de l'information ? self si la fonction définie est uniquement spécifique à l'objet (je pense). En d'autres termes, cette fonction n'est pas définie pour tous les objets de type Employee (à moins que vous n'utilisiez l'exemple de @katrielalex et que vous la définissiez en utilisant ClassName), mais seulement pour l'instance de la classe (comme dans mon exemple "john" dans l'OP).

19voto

Kiril Kirov Points 19081

Essayez avec lambda :

john.greet = lambda : print( 'hello world!' )

Vous serez en mesure de le faire :

john.greet()

EDIT : Merci Thomas K pour la note - cela fonctionne sur Python 3.2 et non pour Python2, où print semble être statement . Mais cela fonctionnera pour lambda sans déclarations (n'est-ce pas ? Désolé, je ne connais que python3.2 ( : )

2 votes

Cela ne fonctionne pas vraiment : les lambdas ne peuvent pas contenir de déclarations.

0 votes

@katrielalex - Fonctionne parfaitement sur mon python 3.2 (avec des parenthèses ajoutées pour les print bien sûr). Quelles déclarations ?

1 votes

@Kirii : Dans Python 2, print est une déclaration. Vous ajoutez des parenthèses parce que dans Python 3, c'est devenu une fonction.

1voto

user465139 Points 727

Vous pouvez également utiliser les "tuples nommés" de l'application collection module standard. Les tuples nommés fonctionnent comme des tuples "ordinaires" mais les éléments ont des noms et vous pouvez accéder aux éléments en utilisant la "syntaxe point". Du module documents de collecte :

>>> # Basic example
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(11, y=22)     # instantiate with positional or keyword arguments
>>> p[0] + p[1]             # indexable like the plain tuple (11, 22)
33
>>> x, y = p                # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y               # fields also accessible by name
33
>>> p                       # readable __repr__ with a name=value style
Point(x=11, y=22)

0voto

Sudheer Points 394

Vous pourriez utiliser AttrDict

>>> from attrdict import AttrDict
>>> my_object = AttrDict()
>>> my_object.my_attribute = 'blah'
>>> print my_object.my_attribute
blah
>>> 

Installez attrdict depuis PyPI :

pip install attrdict 

Il est également utile dans d'autres situations, par exemple lorsque vous avez besoin d'un accès par attribut à des clés de dictée.

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