4 votes

python : clarification de la résolution des noms ?

Je lis la référence python résolution des noms qui se lit comme suit

Une définition de classe est une instruction exécutable qui peut utiliser et définir des noms. Ces références suivent les règles normales de résolution des noms, à ceci près que les variables locales non liées sont recherchées dans l'espace de noms global.

Sur cette base, je m'attendrais à trouver le code suivant

x = 10

def f():
    x = 5

    class Test:
        y = x

    return Test

print(f().y)

pour imprimer 10 Toutefois, il imprime 5 S'agit-il d'une erreur dans la référence ou ai-je mal compris quelque chose ?

5voto

Thierry Lathuille Points 10046

Dans ce cas, les règles "normales" s'appliquent :

x = 'global'

def f():
    x = 'defined in f'

    class Test:
        print(x) # not local, normal rules apply

f()
# defined in f

Dans ce deuxième cas, on s'attendrait à ce qu'un UnboundLocalError: local variable 'x' referenced before assignment si nous étions à l'intérieur d'une fonction :

x = 'global'

def f():
    x = 'defined in f'

    class Test:
        print(x) # unbound local at this time
        x = 'assigned in Test'
        print(x)

Mais pour la première fois print(x) , x sera pris dans l'espace de noms global :

f()
# global
# assigned in Test

0voto

Gildas Points 404

Je pense que @khelwood a donné la réponse. La valeur de la variable :

Test.y

est un nombre entier que vous définissez, mais vous ne donnez jamais x = 10 à la fonction.

Peut-être que ce que vous voulez, c'est en fait.. :

x = 10
def f(x=5):
    class Test:
        y = x
    return Test
print(f().y) #print default 5
print(f(x).y) 

La dernière ligne imprime 10 puisque x est donné à la fonction, et donc la classe définit y comme x

0voto

chepner Points 54078

Vous pouvez voir l'exception en enveloppant f dans une autre fonction qui définit une variable locale x :

x = 10

def g():
    x = 7
    def f():
        class Test:
            y = x

        return Test
    return f()

print(g().y)

Le résultat est maintenant 7, car la recherche de x dans le class contourne la portée locale de g pour trouver la valeur globale de x .

Dans votre code, parce que class établit un nouveau espace de noms mais pas une nouvelle champ d'application , la valeur de x est pris dans la portée locale actuelle, celle de f .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X