Bonjour,
Je cherche à éclaircir un point concernant les objets méthode dans le cadre des classes et instances de classes.
Voici des extraits de la doc
class MyClass:
...."""A simple example class"""
....i = 12345
....def f(self):
........return 'hello world'
x = MyClass() creates a new instance of the class and assigns this object to the local variable x.
A method is a function that “belongs to” an object.
(....)
Valid method names of an instance object depend on its class.
By definition, all attributes of a class that are function objects define corresponding methods of its instances.
So in our example, x.f is a valid method reference, since MyClass.f is a function, but x.i is not, since MyClass.i is not.
But x.f is not the same thing as MyClass.f - it is a method object, not a function object.
Usually, a method is called right after it is bound: x.f()
In the MyClass example, this will return the string 'hello world'.
However, it is not necessary to call a method right away: x.f is a method object, and can be stored away and called at a later time.
For example:
xf = x.f
while True:
....print xf()
will continue to print hello world until the end of time.
What exactly happens when a method is called?
You may have noticed that x.f() was called without an argument above, even though the function definition for f() specified an argument. What happened to the argument?
(....)
the special thing about methods is that the object is passed as the first argument of the function.
In our example, the call x.f() is exactly equivalent to MyClass.f(x).
In general, calling a method with a list of n arguments is equivalent to calling the corresponding function with an argument list that is created by inserting the method’s object before the first argument.
If you still don’t understand how methods work, a look at the implementation can perhaps clarify matters.
When an instance attribute is referenced that isn’t a data attribute, its class is searched. If the name denotes a valid class attribute that is a function object, a method object is created by packing (pointers to) the instance object and the function object just found together in an abstract object: this is the method object.
When the method object is called with an argument list, a new argument list is constructed from the instance object and the argument list, and the function object is called with this new argument list.
Ce qui m’intéresse là dedans c’est la notion d’ ’objet méthode’.
* La doc décrit ce qui se passe quand on appelle une méthode d’une instance pour une exécution.
Si on fait par exempleprint x.f() , le programme fait en réalité
print MyClass.f(x)
Je qualifierai ce genre d’appel de complet, c’est à dire provoquant une exécution.
* Mais la doc explique bien qu’on n’est pas obligé d’appeler complétement une méthode:
Dans ce cas, il n’y a pas d’exécution immédiate. Je qualifierai ce genre d’appel d’incomplet.it is not necessary to call a method right away: x.f is a method object
Je comprends de ceci que dans les faits un appel de fonction commence toujours par la création d’un ’objet méthode’, même quand on fait un appel de méthode pour exécution immédiate.
En termes d’implémentation, je pense que cela doit vouloir dire qu’il y a un constructeur d’ ’objet méthode’ qui est mis en branle. À ce niveau, un objet méthode est un packing de pointeurs vers l’instance et vers la fonction de sa classe.
Ensuite tout dépend de la présence ou non de parenthèses (seules ou avec des paramètres à l’intérieur).
.
- S’il n’y a pas de parenthèses, les choses en restent là, on peut décrire ça comme un appel partiel. On n’a fait que créer un objet avec un nom dessus comme référence directe.
- S’il y a des parenthèses, il y a bien création d’un ’objet méthode’ en coulisses, qui est immédiatement sollicité pour fournir son résultat dans la foulée. Mais dans ce cas, on n’y fait pas attention puisque ce qui importe c’est l’exécution
J’ai donc des questions sur la durée de vie de cet ’objet méthode’ qui concrétise aussi bien les appels de méthode complets que les appels partiels.
- quand l’objet méthode d’une méthode est-il créé ?
Dans le passage où est décrite l’implémentation des appels de méthode, la création d’un objet méthode est décrite pour « When an instance attribute is referenced that isn’t a data attribute »
il me semble évident qu’il faut comprendre référence à un attribut méthode comme étant aussi bien le x.f auquel se limite un appel partiel que le même x.f qui constitue la première partie d’un appel complet x.f() .
De plus une telle référence est immédiatement suivie de «its class is searched», ce qui signifie que l’instance ne dispose pas de ce qu’il faut.
Ce que je comprends donc de ceci, c’est que l’objet méthode d’une méthode n’est pas créé au moment de l’instanciation, mais seulement donc après, quand un appel partiel ou complet a lieu sur cette méthode par une référence explicite.
Il n’y a pas lieu de penser qu’une instanciation constitue une référence implicite aux fonctions de la classe qui déclencherait la création d’un objet méthode pour chacune de ces fonctions.
Ainsi je ne crois pas que des objets méthodes appartiennent aux instances, c’est à dire qu’ils seraient inclus dans l’objet instance lui-même, comme la phrase « A method is a function that “belongs to” an object.
» tend à en suggérer l’idée. Je pense au contraire que ces objets méthodes, quand ils sont créés, le sont à l’extérieur de toute instance.
- combien de temps un objet méthode vit-il, c’est à dire existe-t-il en mémoire vive ?
Je pense pour ma part que lorsqu’un appel partiel du type xf = x.f est fait, un objet méthode est créé et perdure tant que l’espace de nom dans lequel il a été créé ne disparait pas.
L’objet méthode reste “vif“ en mémoire vive.
Par contre, pour un appel complet, une fois l’exécution terminée, aucun nom d’étiquette n’ayant été associé à l’objet méthode, il connait à mon avis le destin des objets qui ne sont plus référencés dans un espace de nom: il flotte dans la mémoire vive sans pouvoir être resollicité et la mémoire qui lui a été allouée lors de l’appel sera libérée dès que le garbage collector fera un tour de nettoyage.
Dans ce cas, il s’agit d’un objet méthode créé à la volée et s'évanouissant dès que son action est terminée.
Motif de ce questionnement:
J’envisage créer dans un programme une liste d’instances de classe [instance 1, instance 2....instance 350....].
Je me demande quelle consommation de mémoire va faire cette liste d’instances.
Cette consommation est suceptible d’être notablement plus importante dans le cas où chaque instance dans la liste comporterait dans son enveloppe des objets méthodes avant même que les méthodes aient été appelées, et ce d’autant plus si les objets méthodes étaient créés au moment de l’instanciation de chaque méthode. Car il est clair qu’il n’y a pas d’objet méthode commun à toutes les instances d’une même classe et qu'il y aurait donc autant d'objets méthodes que d'instances (plus même) dès la création des instances.
Je voudrais savoir à quoi m’en tenir. Je pense personnellement que les objets méthodes sont créés à la volée, et en dehors d’une classe d’ailleurs, quand il y a appel de la méthode, mais j’aimerais une confirmation sur ce point fondamental.
Qu’en pensez vous ?
PS
Pour rendre la question un peu plus concrète:
si on a à définir et traiter 350 instances et que chaque instance est alourdie de tous les objets méthodes correspondant aux fonctions de sa classe,
on peut avoir intérêt, pour économiser la mémoire, de traiter tout de suite après sa définition toute instance,
au lieu de créer d’abord la collecion des 350 instances et de les traiter ensuite.
Partager