Python: la résolution de Nom; afin de la fonction def du
J'ai un exemple très simple:
#!/usr/bin/env python
#a() # 1: NameError: name 'a' is not defined
#b() # 1: NameError: name 'b' is not defined
#c() # 1: NameError: name 'c' is not defined
def a():
c() # note the forward use here...
#a() #2: NameError: global name 'c' is not defined
#b() #2: NameError: name 'b' is not defined
#c() #2: NameError: name 'c' is not defined
def b():
a()
#a() #3: NameError: global name 'c' is not defined
#b() #3: NameError: global name 'c' is not defined
#c() #3: NameError: name 'c' is not defined
def c():
pass
a() # these all work OK...
b()
c()
J'ai 3 fonctions nommé a()
, b()
et c()
définie dans un source Python fichier dans l'ordre alphabétique. Le corps de chaque définition de fonction est un appel à l'une des autres fonctions. Vous pouvez voir par mes commentaires que j'ai d'avoir l'appel initial à la première de ces fonctions au-DESSOUS de leurs définitions (dans le fichier texte), mais vous n'avez pas nécessairement besoin de définition d'une fonction par rapport à une autre fonction qui l'appelle.
Certes, il semble être de pratique courante d'avoir le premier code exécutable ci-dessous toutes les définitions de fonction (en Python et beaucoup d'autres langues), et maintenant, je peux voir pourquoi. En C et C++, les fichiers d'en-tête en prendre soin. En Pascal, vous devez disposer de définitions de nom avant leur utilisation.
Supposons, par exemple, que vous avez ceci en Python:
def a(a_arg): c(a_arg)
def b(b_arg): a()
def c(a_arg,b_arg): b(b_arg)
a(1)
Il échouera correctement avec TypeError: c() takes exactly 2 arguments (1 given)
au moment de l'exécution où les autres erreurs sont les temps de compilation. (en C, cela permettrait de compiler puis échouent mystérieusement...)
En Perl, depuis les sous-routines noms sont GÉNÉRALEMENT réglés au moment de l'exécution, vous pouvez avoir Perl définitions et le code dans n'importe quel ordre:
#!/usr/bin/env perl
a();
b();
c();
sub a{ c(); }
sub b{ a(); }
sub c{ return; }
En C, c'est soit une erreur ou un avertissement (dépendant de l'implémentation) d'utiliser une fonction qui n'a pas été conçu et ne doit pas être ignoré.
Vous pouvez avoir ceci:
void a(void) { c(); } /* implicitly assumed to be int c(...) unless prototyped */
void b(void) { a(); }
void c(void) { return; }
int main(void) {
a();
return EXIT_SUCCESS;
}
Mes hypothèses et de la confusion: Si Python n'a pas de résoudre les sous-routines noms jusqu'à l'exécution, pourquoi la source de la phase de compilation échoue avec l'avant de la déclaration de la sous-routine noms qui n'ont pas encore été définie? Est-il documenté quelque part (autre que par l'observation de tout autre code) que vous ne pouvez pas avoir de code dans un fichier source au-dessus de définitions de sous-programmes?
Il semble que Python a des éléments de dynamique de résolution de nom (l'utilisation de c()
dans a()
avant sa définition ci-dessous dans le fichier source) et des éléments de statique de résolution de nom (l'échec de Python pour exécuter l'appel à a()
si placé au-dessus de sa définition dans le fichier source.)
Est-il une version de Python de CE DOCUMENT qui couvre le cycle de vie d'un exécutable Perl et comment les noms sont résolus entre le fichier source de l'interprétation et de l'exécution?
Est là une description définitive quelque part sur l'ordre des définitions pour un script Python que les états fonctions peuvent avoir de l'avant les définitions d'autres sous-routine dans les noms, mais le code principal ne peut pas?
De modifier et de conclusion
Après quelques fougueux commentaires, et quelques recherches de mon côté, j'en ai conclu que ma question est vraiment plus sur la façon dont les noms sont résolus, et comment les espaces de noms, des champs d'application et les modules sont définis dans Python.
De carot-haut:
"un" callable " doit être défini avant d'être appelé dans l'espace de noms courant."
et ce lien sur les champs et les noms
De S. Lott:
"Lorsqu'un nom est utilisé dans un bloc de code, il est résolu à l'aide de la plus proche joignant la portée."
et ce lien à l'exécution de vie d'un script Python.
De l'Python documents:
"Un champ d'application définit la visibilité d'un nom au sein d'un bloc." À partir de la Python modèle d'Exécution
"Un module peut contenir des instructions exécutables ainsi que des définitions de fonction." dans plus sur les modules
"En fait, les définitions de fonctions sont aussi des "états" qui sont "exécutés"; à l'exécution d'un module de fonction de niveau entre le nom de la fonction dans le module mondial de la table des symboles." dans la note de bas de page s'y rapportant.
Et de ma propre réalisation (Duh!) que:
-
Chaque source Python fichier est traité comme un "module" en Python: "Un module est un fichier Python contenant les définitions et les déclarations."
-
Contrairement à Perl (j'ai plus d'expérience avec) Python exécute les modules sont en cours de lecture. D'où l'incapacité de l'un est immédiatement exécutable déclaration faisant état d'une fonction n'est pas encore défini dans le même module.
- "avant définitions"? Qu'est-ce que cela signifie? Êtes-vous demander à propos de l'avant "références"? La réponse est trivialement oui. Je suis désolé, mais la question me confond.
- J'ai utilisé des "énoncés définition de" parce que de la question d'origine d'être sur quand et où
def c()
est utilisé en relation avecdef a()
et en relation avec code qui exécute immédiatement. En C et Pascal, il serait appelé un "avant" ou "externe" déclaration par un prototype de fonction dans un en-tête ou autrement avant de l'utiliser. En Python, il semble à la matière mais pas les autres. Encore une fois: ma question est de savoir où est la documentation qui couvre ce? Ce qui peut être résolu au moment de l'exécution et de ce qui ne peut l'être? J'ai lu le site web de Python docs. - J'ai toujours pensé de "référence vers l'avant", car le terme utilisé dans les deux passes compilateur Python qui ne l'est pas.
- Vous dites que la réponse est "trivialement oui." Comme un exemple supplémentaire de ma question: pourquoi est-ce que vous avez
def a(): return Global_B
avec Global_B être une référence vers l'avant / déclaration d'une déclaration ci-dessous ou ailleurs, mais vous ne pouvez pas avoir une référence directe à la déclaration qui définit une fonction en dehors d'une fonction? Qui n'est pas négligeable." Soit c'est un hasard effets secondaires ou formellement définis dans la spécification du langage dans un document que je n'ai pas lu. - Je ne suis pas sûr de ce que vous pourriez être à la recherche pour. La résolution de nom se produit lorsque le nom est rencontré. Il ne peut y avoir un "avant" références car il n'existe pas de "déclarations" dans n'importe quelle forme. Votre question est très déroutant parce qu'il utilise non-Python des concepts comme la "déclaration" et "en avant".
- J'ai dit ce que je cherchais: Un Python version de Perl document.
- En plus de cette demande, la question est pleine de non-python concepts qui le rend très difficile à comprendre la question ou de déterminer ce que vous besoin. Python n'est pas Perl. En continuant à exiger un Python document qui comme par magie correspond à un document pour l'un de complètement différent de la langue me confond. Les langues ne correspondent pas. Je ne vois pas comment un document pour une langue doivent correspondre document dans une autre langue.
- Il évident que vous connaissez Python beaucoup mieux que je ne. J'ai été à l'aide de Python 3 mois et j'ai été à l'aide de C et Perl depuis des années. Que j'allais tomber en arrière sur des concepts qui me sont familiers ne devrait pas être surprenant. Si vous apprenez quelque chose que vous ne savez pas, la même chose peut vous arriver. Je n'ai pas "exiger" quoi que ce soit. J'ai posé une question sur une question et une réponse du site. Vous avez gardé de me demander de préciser; j'ai offert ce document comme un exemple de ce que je cherchais. Quel que soit le langage, les concepts peuvent être similaires. N'est-ce pas ce site pour poser des questions et obtenir des réponses?
- de la langue, les concepts peuvent être similaires". Désolé, je n'ai pas trouvé que cela soit vrai. Je m'excuse, mais des langues que je connais (y compris C, Java et Python) les concepts ne voyage pas bien entre les langues. La répétition de non-Python concepts dans un Python question me confond. Je m'excuse d'être dense, mais je ne peux pas la carte des concepts comme la "déclaration" d'une langue qui manque entre eux.
- ne voyage pas bien entre les langues", Indépendamment de la langue, il doit être un concept de résolution de nom de code et de données. Le comportement que je voyais en Python avaient éléments implicites dynamique, au moment de l'exécution de la résolution de nom et d'autres comportements qui implicites statique de la résolution. J'essaie juste de comprendre comment Python résout les noms. J'en ai conclut-il vraiment plus sur la façon Python charge des modules, et l'individu de l'espace de noms associés à l'exécution de la portée. Si je savais que lorsque j'ai posé la question -- je n'aurais pas posé la question.
- de résolution de nom". D'accord. Des mots comme "déclaration anticipée", cependant, me confond dans un Python contexte. Manque de déclarations, la question n'était pas raisonnable. Si la question portait sur "la résolution de nom", il aurait pu être un peu plus clair.
- J'ai fait les modifications que vous avez suggéré. Merci pour votre aide!
Vous devez vous connecter pour publier un commentaire.
L'ordre des définitions est tout simplement "tout doit être défini avant de vous appeler". C'est assez bien.
modifier (inclure la réponse dans les commentaires, les élucidé):
La raison quelque chose comme
fonctionne lorsque vous avez
a()
danscall_a()
avanta
est même définie comme une fonction est parce que Python n'recherche de valeurs, de symboles, sur un besoin base. Lorsquecall_a
est évalué,a()
appel est essentiellement stockées en tant que pseudo-code binaire des instructions pour "regarder cea
est et de l'appeler" lorsque vient le temps, ce qui n'est pas jusqu'à ce que vous descendez à la réalité de l'invocation de lacall_a()
au fond.Voici ce que l'démonté le bytecode de
call_a
ressemble (viadis.dis
):Donc, fondamentalement, lorsque vous appuyez sur
call_a
, il charge tout ce qui est stocké commea
sur la pile, il appelle une fonction, puis apparaît la valeur de retour de congé avant de retournerNone
, qui est ce qui implicitement se passe pour tout ce qui n'est pas explicitement retour (call_a() is None
retourneTrue
)a()
avecc()
ci-dessous manquerait à C.c
dans la table des symboles lorsque quelqu'un m'appelle", mais à ce moment, il n'a pas d'importance.c()
nécessaires pour être connu au moment dea()
était en cours de traitement par Disponible. Depuisa()
est au-dessus dec()
c'est une définition de l'avant. En C / Pascal / Objective-C, ce serait un avertissement ou une erreur sans un fichier d'en-tête de prototypec()
Ma question est: existe-Il une Version de Python de CE DOCUMENT qui couvre le cycle de vie d'un programme en Perl. Perl résout au moment de l'exécution, de sorte que les définitions peuvent être dans n'importe quel ordre. Qu'est-Python faire et où puis-je en savoir plus est 1 phrase.Suite aux différents commentaires et de la difficulté à comprendre certains Perl concepts à partir d'un Python de l'histoire, permettez-moi de prendre une fissure à ce. Veuillez réinitialiser votre cerveau sur certaines des choses que vous avez appris en Perl. Ils ne s'appliquent pas en Python. (Et vs vs...)
Il y a pas déclaration en Python. Aucun. Techniquement, TOUTES les fonctions sont des objets anonymes; ils ont juste arriver à être lié au nom que vous avez utilisé pour le définir. Vous pouvez re-lier à volonté.
Le dictionnaire de ces fonctions peut être trouvé à l'aide de la les habitants() fonction comme ceci:
Si Python nécessaires
b()
être défini AVANT d'écrirea()
, serait-ce un problème dans l'interpréteur Python. Vous devez écrire tout ce que vous des fonctions dans un ordre strict.Depuis tous les builtin les noms de fonction sont juste délimitée noms, vous pouvez facilement remplacer les fonctions internes:
Il est beaucoup plus difficile (mais possible) pour remplacer built-ins en Perl. (L'inconvénient ici est une erreur de frappe
def [builtin]:
peut involontairement remplacer la fonction intégrée sans avertissement)La meilleure description que je puisse vous référer à des noms et à la portée de Python est en fait le tutoriel sur Classes: la section 9.2
Il n'est pas réellement le chapitre et le verset pourquoi
def
besoin pour arriver avant le code de l'exécutable, car ce n'est pas un énoncé vrai. Considérer:Ou encore:
Ce qui est vrai est que un callable doit être défini avant d'être appelé dans l'espace de noms courant. Donc, généralement, au-dessus du point d'être appelé par le code exécutable dans un fichier texte ou d'un module. Chaque fonction possède son propre espace de noms; des appels à d'autres fonctions qui ne sont pas encore définis uniquement échouer lorsque cette fonction est appelée dans ce local et de l'exécution d'espace de noms, - lorsque le callable est appelée à partir de l'espace de nom de la fonction. C'est pourquoi vous pouvez avoir ce qui ressemble à une "déclaration anticipée" dans votre exemple. Le module d'appel d'un "forward" callable en dehors d'une fonction échoue parce que la fonction
def
n'a pas encore été exécutés de sorte qu'il n'est pas dans l'espace de noms courant.C'est exactement la même qu'en C/C++ etc. Vous ne pouvez pas utiliser quelque chose jusqu'à ce qu'il existe. En C/C++, vous ne pouvez pas se référer à quelque chose jusqu'à ce qu'il ait été déclarée. Rappelez-vous qu'un fichier Python est traitée à partir du haut vers le bas donc, si vous essayez d'appeler une fonction ou une référence à une variable qui n'existe pas, alors il échoue.
http://docs.python.org/reference/executionmodel.html
Que c'est. Il n'y a pas de concept de "l'avant" ou "arrière" ou "déclaration" ou quelque chose comme ça.
You should, perhaps, review the Python language reference.
ettrivially yes
etContinuing to demand a Python document that magically matches a document for an utterly different language
etI'm puzzled how you could claim that [you RTFM] and yet, somehow, not have found this
peut paraître condescendant, réprimander et frustrant pour quelqu'un sur la partie abrupte de la courbe d'apprentissage. Il faut beaucoup de temps et de travail pour maîtriser tout cela. Ce qui est évident pour vous, peut-être pas pour d'autres.Je sais que cette question a été répondu depuis un certain temps maintenant, mais j'ai aussi eu de la difficulté à comprendre et aimerions montrer comment j'ai trouvé la réponse avec un exemple simple:
Dans l'exemple ci-dessus, globals serait d'afficher l'emplacement de la fonction qui a été défini avec le nom b si votre exécutable principal définis dans le code d'une fonction avec le nom b. Si pas, le globals serait vide et l'appeler pour un résultat
comme dans l'exemple du loup. Ce que cela signifie, c'est que, bien que les noms de fonctions doivent être déclarées avant qu'ils sont appelés pour eux d'exister dans l'espace de noms des principaux exécution de code, la fonction principale de l'exécution de code appelle déjà les définitions qui se trouvent dans la main, qui est pourquoi la fonction des appels de fonctions n'a pas besoin de suivre un ordre strict.