10
votes

Lequel est plus fondamental: fonctions python ou méthodes d'objet Python?

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: xxx

si je regarde dir (fred) , je vois Il a un attribut nommé __ appel __ . Mais dir (fred .__ appel __) aussi a un attribut nommé __ appel __ . Donc, fred .__ appelez __.__ appel __ et ainsi de suite. Les identifiants de cette chaîne de __ appelent __ 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?

qui est plus fondamental: fonctions ou méthodes d'objet?


1 commentaires

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.


3 Réponses :


2
votes

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.

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.

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. :)


0 commentaires

1
votes

qui est plus fondamental: fonctions ou des méthodes d'objet?

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 __ 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 attributs Func_xxx de votre fonction à la place, avec le partecode réel étant stocké sous forme func_code ).

é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? "


0 commentaires

4
votes

Réponse courte: les deux sont fondamentaux, .__ appel __ () sur les fonctions est juste une astuce virtuelle.


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.

réponse longue

au niveau le plus fondamental, on peut dire que Python n'aura que 2 opérations:

  • Accès d'attributs: obj.attr
  • Appel de la fonction: appelable (args)

    Appels de méthode - obj.method (args) - ne sont pas fondamentaux. Ils se composent de 2 étapes: récupération de l'attribut obj.method (qui donne un objet "méthode lié" appelable ") et l'appelant avec args . .

    D'autres opérateurs sont définis en termes d'entre eux. Par exemple. x + y essaie x .__ Ajouter __ ( y) , retomber à d'autres combinaisons similaires si cela ne fonctionne pas.

    réponse infiniment longue?

    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 obj .__ Call__ (args) et obj .__ getattribute__ (Nom) ?!?
    Est-ce que Turtles est-il complètement descendu?!?

    L'astuce est que les opérations sur un objet sont définies en appelant des méthodes de son type : type (obj). __ (obj, args) et type (obj) .__ getattribute __ (obj, nom) . Que BTW signifie que je vous ai menti, et il y a une troisième opération fondamentale:

    • Obtenir le type d'objet: type (obj)

      OK, ce n'est toujours pas utile. type (obj). __ appel __ (...) 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 type une fonction, généralement une fonction, objet ou type - et pour leur attribut les appels d'accès et de fonction d'attribut sont fondamentales.

      Ainsi, lorsque vous appelez une instance d'une classe personnalisée, c'est implémenté via sa méthode __ __ . Mais son __ appel __ est probablement une fonction normale - qui peut être appelée directement. Fin du mystère.

      De même sur __ getattribute __ - 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 ).

      Le rideau devant l'homme

      alors pourquoi même une fonction a un fred .__ appel __ 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.

      De même, tous les objets ont obj .__ getattribute __ et obj .__ Classe __ , mais pour les types intégrés, il expose les opérations fondamentales à la place de définir it.

      Petit imprimé

      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.

      Mais l'histoire que je t'ai dit aurait pu être vraie, et cela réduit la question de son centre: pourquoi .__ appel __ () et .__ () ne sont pas un infini Récursion.


0 commentaires