2013-04-04 3 views
1

У меня есть следующие модули:Python функция обзорное с импортом

main.py

import my_import 

my_import.a_func() 

my_import.py

FOO = "foo" 
BAR = [] 

def a_func(): 
    BAR.append("bar") #ok 
    FOO = FOO + "foo" #UnboundLocalError: 
        #local variable 'FOO' referenced before assignment 

Это, вероятно, связано с импортом, но как?

[EDIT]

Из ответов я получаю это не импортирование, что является crulpit, но follwing все еще странно:

FOO = "foo" 
BAR = [] 
def a_func(): 
    BAR.append("bar") 
    print(FOO) 
a_func() 

-> печатает "Foo"

FOO = "foo" 
BAR = [] 
def a_func(): 
    BAR.append("bar") 
    print(FOO) 
    FOO = FOO + "foo"  
a_func() 

-> терпит неудачу с "UnboundLocalError: локальная переменная 'Foo' обращаться до присвоения" И не распечатывается "Foo"

Похоже, что интерпретатор ищет назначения в текущей области до того, как он действительно выполнит код.

ответ

5

Когда Python разбирает определение функции, он отмечает все имена переменных, которые находятся на левой стороне операторов присваивания, например

FOO = FOO + "foo" 

Он регистрирует все такие имена переменных, как локальных переменных.

Позвольте мне подчеркнуть, что оператор присваивания приводит Python зарегистрировать FOO в качестве локальной переменной в момент определения функция разобранного, не тогда, когда функция вызывается. Поэтому позже, когда вызывается функция, даже ссылки на FOO, которые происходят до назначения, по-прежнему относятся к локальной переменной и могут поднять UnboundLocalError.

def a_func(): 
    BAR.append("bar") 
    print(FOO)  #<--- "Freaky" UnboundLocalError occurs here! 
    FOO = FOO + "foo" 

Так внутри a_func, FOO является локальной переменной. В случае, когда нет инструкции print(FOO), Python достигает назначения и сначала оценивает правую часть. Он встречает имя переменной, FOO, распознает его как локальную переменную и спрашивает, каково ее значение? Это не имеет значения! Поэтому он поднимает UnboundLocalError.

Чтобы исправить, используйте global FOO объявить, что FOO внутри a_func относится к глобальной переменной:

FOO = "foo" 
BAR = [] 

def a_func(): 
    global FOO 
    BAR.append("bar") #ok 
    FOO = FOO + "foo" assignment 

В отличие от этого, BAR.append('bar') работает, потому что Python первый ищет переменную BAR - она ​​не считает это локальная переменная, так как не было присвоения формы BAR = .... Он находит BAR в глобальной области, затем просматривает свой метод добавления, а затем мутирует BAR. Таким образом, вы можете мутировать BAR, но не можете назначить FOO (без инструкции global FOO.)

+0

Спасибо за внутреннее объяснение. Позволяет довести это до Closure (Bwhoeehaaaa) – RickyA

2

Нет, это не имеет никакого отношения к импорту. Это произойдет и в одном модуле или скрипте, даже в интерактивном интерпретаторе.

минимальный пример был бы

a = 1 
def f(): 
    a = a + 1 

Это назначение делает a локальной переменной. В этом случае глобальный затенен и, следовательно, недоступен.

Вы можете обойти эту ситуацию с global, если вы хотите изменить глобальный один:

a = 1 
def f(): 
    global a 
    a = a + 1 

или с по-разному именем локальной variabl, если вы хотите, чтобы сохранить изменения локально:

a = 1 
def f(): 
    b = a 
    b = b + 1 
0

Я мог ошибаться, но может ли проблема в FOO и BAR быть проблемой? Похоже, вы вошли в другую область. Попытайтесь маркировать FOO и BAR в своем методе как глобальные.

Смежные вопросы