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:

  1. 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."

  2. 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 avec def 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!

InformationsquelleAutor dawg | 2011-02-08