J'essaie d'obtenir une compréhension conceptuelle de la nature des fonctions et des méthodes de Python. Je reçois que les fonctions sont en réalité des objets, avec une méthode appelée lorsque la fonction est exécutée. Mais cette méthode d'objet fonction est-elle une autre fonction?
Par exemple: p> si je regarde qui est plus fondamental: fonctions ou méthodes d'objet? P> P> dir (fred) code>, je vois Il a un attribut nommé __ appel __ code>. Mais dir (fred .__ appel __) code> aussi em> a un attribut nommé __ appel __ code>. Donc, fred .__ appelez __.__ appel __ code> et ainsi de suite. Les identifiants de cette chaîne de __ appelent __ code> Les objets suggèrent qu'ils sont tous distincts. Sont-ils vraiment des objets ou constituent-ce un truc de faible niveau de l'interprète? P>
3 Réponses :
Pas spécifiquement une réponse python, mais au niveau le plus bas, le processeur ne comprend que des actions et des variables. De cela, nous extraperons des fonctions et des variables et des fonctions que nous extrapolons des objets. Donc, d'une perspective de programmation de bas niveau, je dirais que la chose la plus fondamentale est la fonction. P>
Ce n'est pas nécessairement vrai de Python dans le sens pythonique et est probablement un bon exemple de la raison pour laquelle il n'est pas toujours bénéfique d'examiner profondément la mise en œuvre de la langue en tant qu'utilisateur. :) Penser à une fonction comme un objet est certainement la meilleure réponse à Python elle-même. P>
Au début, je pensais que vos appels suivaient dans la bibliothèque Python, mais la méthode. Call a les mêmes propriétés que toute autre méthode. Ainsi, cela explore de manière récursive, je pense avoir joué avec le CLI Python pendant quelques minutes; Je pense que c'est une façon douloureuse d'explorer l'architecture et sans nécessairement un bogue une propriété de la manière dont Python gère des objets sous les couvertures. :) p>
qui est plus fondamental: fonctions ou des méthodes d'objet? P> blockQuote>
Je pense que la meilleure réponse pourrait être "ni". Voir le Modèle d'exécution une partie de la référence Python, où elle fait référence à des "blocs". C'est ce qui est réellement exécuté. Le
__ appel __ code> La chose que vous avez accroîchée dans la recherche infinie d'une fin n'est qu'une enveloppe qui sait exécuter le bloc de code (voir les différents attributsFunc_xxx CODE> de votre fonction à la place, avec le partecode réel étant stocké sous formefunc_code code>). p>également pertinent, le Définitions de la fonction , qui fait référence à "Un objet de fonction [être] (une enveloppe autour du code exécutable pour la fonction)". Enfin, il y a le terme appelable , ce qui pourrait également être une réponse à "qui est plus fondamental? " p>
Réponse courte: les deux sont fondamentaux, Le reste de cette réponse est un peu compliqué. Vous n'êtes pas obligé de le comprendre, mais je trouve le sujet intéressant. Soyez averti que je vais présenter une série de mensonges, en les fixant progressivement. P>
au niveau le plus fondamental, on peut dire que Python n'aura que 2 opérations: p>
Appels de méthode - D'autres opérateurs sont définis en termes d'entre eux. Par exemple. jusqu'à présent si bon. Mais l'accès et l'accès à l'attribut eux-mêmes sont également définis en termes de L'astuce est que les opérations sur un objet em> sont définies en appelant des méthodes de son type em>: OK, ce n'est toujours pas utile. Ainsi, lorsque vous appelez une instance d'une classe personnalisée, c'est implémenté via sa méthode De même sur alors pourquoi même une fonction a un De même, tous les objets ont La première affirmation selon laquelle Python avait 2 opérations fondamentales était en réalité un mensonge complet. Techniquement, tous les opérateurs Python ont une opération "fondamentale" au niveau C, exposée à la cohérence via une méthode et des classes personnalisées peuvent redéfinir ces opérations à travers des méthodes similaires. P>
Mais l'histoire que je t'ai dit aurait pu être vraie, et cela réduit la question de son centre: pourquoi .__ appel __ () code> sur les fonctions est juste une astuce virtuelle. P>
réponse longue h2>
obj.attr code> li>
appelable (args) code> li>
ul>
obj.method (args) code> - ne sont pas fondamentaux. Ils se composent de 2 étapes: récupération de l'attribut obj.method code> (qui donne un objet "méthode lié" appelable ") et l'appelant avec args code>. P>.
x + y code> essaie x .__ Ajouter __ ( y) code> , retomber à d'autres combinaisons similaires si cela ne fonctionne pas. P>
réponse infiniment longue? h2>
obj .__ Call__ (args) code> et obj .__ getattribute__ (Nom) Code> ?!?
Est-ce que Turtles est-il complètement descendu?!? P>
type (obj). __ (obj, args) code> et type (obj) .__ getattribute __ (obj, nom) code>. Que BTW signifie que je vous ai menti, et il y a une troisième opération fondamentale: p>
type (obj) code> li>
ul>
type (obj). __ appel __ (...) code> implique toujours un accès d'attributs et un appel, cela devrait donc continuer à annoncer l'infinitum? Le frott est que finalement vous frappez un type em> type em> une fonction, généralement une fonction, objet code> ou type code> - et pour leur attribut les appels d'accès et de fonction d'attribut sont em> fondamentales. p>
__ __ code>. Mais son __ appel __ code> est probablement une fonction normale - qui peut être appelée directement. Fin du mystère. P>
__ getattribute __ code> - Vous pouvez le fournir à Définir l'accès à l'attribut de votre classe, mais la classe elle-même implémente l'accès à l'attribut fondamentalement (sauf s'il a une coutume métaclass em>). p>
Le rideau devant l'homme h2>
fred .__ appel __ code> méthode? Eh bien, ce n'est que de la fumée et des miroirs que Python tire pour brouiller la différence entre les types de construction et les classes personnalisées. Cette méthode existe sur tous les objets appelables, mais appeler une fonction normale ne doit pas nécessairement passer - les fonctions sont fondamentalement appelables. P>
obj .__ getattribute __ code> et obj .__ Classe __ code>, mais pour les types intégrés, il expose em> les opérations fondamentales à la place de définir em> it. p>
Petit imprimé h2>
.__ appel __ () code> et .__ () code> ne sont pas un infini Récursion. P>
Les ID de l'objet d'appel suggèrent qu'ils sont générés comme demandé: parfois je vois des doublons à différents niveaux, et parfois je vois différents identifiants au même niveau.