9
votes

Python Méthode Recherche, Statique vs. Instance

Jusqu'à une heure il y a une heure, j'étais convaincu que dans Python FOO () .Bar () n'était rien de plus qu'une main courte pour foo.bar (foo ()) qui transmet l'instance comme premier paramètre. Dans cet exemple, les deux dernières lignes font (apparemment) la même chose: xxx

mais maintenant j'ai un animal de classe qui a une méthode statique remplie () qui renvoie une liste de tous les animaux connus de homme. Aussi chaque instance d'animal a une méthode remplie () qui remplit les propriétés de l'instance avec des valeurs aléatoires. xxx

Le code fonctionne bien, mais ce qui m'a fait suspect était le fait que imprimer animal.populer (qux) appelé la méthode de population statique (et donc renvoyé une liste et n'a pas peuplé de pauvres qux). Donc, apparemment, ma conviction que foo () .bar () n'était rien de plus qu'une main courte pour foo.bar (foo ()) est faux. < P> Cela soulève diverses questions pour moi:

  1. Que se passe-t-il lorsque j'appelle foo () .bar () ?
  2. Que se passe-t-il lorsque j'appelle foo.bar (foo ()) ?
  3. Y a-t-il une différence interne entre les deux?
  4. Suis-il manque un concept fondamental de Python?
  5. Si vous deviez écrire une classe dont la méthode de remplissage statique fait autre chose que la méthode de la population invoquée sur une instance de cette classe, ce qui serait la voie à suivre?

    (oui, il doit être le même nom.)


11 commentaires

Un titre plus intéressant serait "Python Méthode Recherche, Statique vs. Instance". Vous pouvez obtenir plus de réponses en utilisant cette terminologie, il est un peu plus technique et attrayant.


@Santiago Merci pour l'entrée. J'ai changé le titre.


Tous les espaces supplémentaires autour du () me fait mal aux yeux


De gustibus non-est discutandum. Mine blessée avec des choses comme "," .join (carte (Lambda x: "% s"% x, zip (* paires) [1])) . Comment WhitSpace Gusto se rapporte-t-il à la recherche de méthode?


Je ne suis pas sûr du point d'avoir un staticmethod si vous ne l'appelez jamais d'une instance. Êtes-vous confondre cela avec une méthode statique d'une langue différente peut-être? ClasseMethod a plus de sens ici


Corrigez-moi si je me trompe, mais à Pyhton Staticmethod et que ClassMethod ne diffèrent que si la classe est adoptée comme premier argument ou non. Comment puis-je éventuellement invoquer une méthode statique (classe) à partir d'une instance comme vous le suggérez? L'idée d'une méthode statique (classe) n'est-elle pas invoquée d'une classe plutôt que d'une instance?


qux.populer appellera toujours la méthode d'instance puisque vous le réglez inconditionnellement. qux. __ classe __. peupler () appellerait la méthode sur la classe


Utilisation de * args Juste pour que la population fonctionne parfois comme un staticmethod et parfois comme une classe de classe semble être un design pauvre pour moi. Peut-être qu'il vaut mieux écrire des tests pour clarifier la manière dont vous utiliserez cette classe et qu'une nouvelle approche devienne apparente


Merci, je pense que peu à peu, je commence à grok ceci en plénitude.


L'idée d'utiliser cela est tout comme dans l'exemple. J'ai une classe qui représente des objets que j'ai dans la présidence Leayseur (DB ou autre chose). Pensez à un orme léger. Lorsque j'appelle classe.Load je veux un tableau de toutes les instances que je trouve dans la DB. Si j'appelle la charge d'une instance, je souhaite peupler cette même instance avec des données persistantes en fonction de certaines variables de membre définies dans cette instance.


BTW ça marche aussi sans * args . Le paramètre était un reste d'un autre test.


3 Réponses :



0
votes

qnx.populer () d'abord sur l'instance qnx pour peupler . Si ce n'est pas là, le __ mro __ est suivi jusqu'à ce que quelque chose appelé peuplule est trouvé.

animaux.populat (qnx) saute la première étape de la recherche ci-dessus


6 commentaires

Merci beaucoup. J'ai besoin de temps pour digérer cela.


Y a-t-il un moyen de tracer avec MRO en Python?


@Hyperboreus, la classe a un __ mro __ attribut


Une chose que je ne comprends pas. Utilisation de Classe FOO (Objet): DEF BAR (* args): Imprimez "BAZ" , pourquoi foo () .Bar () et foo .Bar (foo ()) travail, mais foo.bar () n'est pas?


@Hyperboreus, ce dernier est une méthode non liée. Ceci est plus évident que vous suivez la convention habituelle d'utiliser un moi explicite. DEF Barre (Self, * args) . Les 2 premiers passent une instance comme auto . Le premier parce qu'il s'agit d'une méthode liée, la seconde parce que vous passez explicitement une instance. Écriture def bar (* args) ne vous permet pas de ne pas passer à ne pas passer dans une instance, il ne le dissocie simplement comme premier élément de args


Entendu. Et bon d'entendre que Python 3 a terminé le paradigme lié / non lié.



2
votes

à la différence entre foo (). bar (), foo.bar (foo ()) et foo.bar () (comme réponse parce que je me suis inscrit hier et je ne peux pas encore poster des commentaires) - c'est parce que Parmi les méthodes de Python (<3.0) de méthodes "liées" et "non liées" - il exige de strictement que, sauf avec @sticMethod ou @ClassMethod, les appels de méthode ont une instance associée à eux. Il n'y a pas vraiment de moyen plus simple de l'expliquer que quelque chose que vous devez vous rappeler. Heureusement, cela a changé à Python 3 - le concept de méthodes "liées" et "non liées" comme des choses distinctes a disparu, et foo.bar () fonctionne parfaitement pour votre exemple.


1 commentaires

Je viens de passer de Python2.7 à Python3.2 et maintenant, je suis des expériences moins "surprises" qu'auparavant.