Конфликт локальных/глобальных переменных в Python: кто из нас прав?
=====================================================================

 Тут всё работает:
```
x = 10;
def my_func():
	print(x);
my_func();
```
  

А тут не работает: 
```
x = 10;
def my_func():
	print(x);
	x=5; #добавили
my_func();
```
  

Мы с приятелем спорим, почему так?  

Версия приятеля: Питон увидел, что локальная переменная сперва используется в print, а потом создаётся (а ведь надо наоборот!)  

Моя версия: Питон сначала хотел сунуть в print внешнюю переменную, а потом увидел, что у него есть локальная.  

Кто прав? 

 Марк Лутц - "Изучаем Python", глава 20, страница 596  

> Как известно, имена, которым выполняется присваивание внутри функции, по умолчанию рассматриваются как локальные – они располагаются в области видимости функции и существуют только во время работы функции. Но я еще не говорил, что локальные переменные определяются статически, во время компиляции программного кода в инструкции def, а не в соответствии с операциями присваивания, производимыми во время выполнения. Эта особенность становится причиной появления самых причудливых сообщений в группе новостей, получаемых от начинающих программистов. Обычно, если внутри функции имени не присваивается какое-либо значение, поиск его будет производиться в области видимости объемлющего модуля. Но посмотрите, что произойдет, если добавить инструкцию присваивания переменной X после ее использования.  
>   
> 
> ```
> X = 99
> >>> def selector():
> ... print(X) # Переменная еще не существует!
> ... X = 88 # X классифицируется как локальная переменная
> ... # То же самое происходит при “import X”, “def X”...
> >>> selector()
> Traceback (most recent call last):
> ...текст сообщения об ошибке опущен...
> UnboundLocalError: local variable ‘X’ referenced before assignment
> ```
>   
> 
> Было получено сообщение о том, что переменная не определена, но причина его появления не очевидна. Этот программный код компилируется интерпретатором во время ввода в интерактивной оболочке или во время импорта модуля. Вовремя компиляции Python обнаруживает операцию присваивания переменной X и делает вывод, что X – это локальное имя везде в теле функции. Но во время выполнения функции, из-за того, что к моменту вызова инструкции print операция присваивания еще не производилась, интерпретатор сообщает о том, что имя не определено. Согласно этому правилу использования имен, он говорит, что обращение к локальной переменной X произведено до того, как ей было присвоено значение. Фактически любая операция присваивания внутри функции создает локальное имя. Операция импортирования, =, вложенные инструкции def, вложенные определения классов и так далее – все трактуются именно таким образом. Проблема возникает из-за того, что операция присваивания делает имена локальными для всей функции, а не только для той ее части, которая следует за инструкцией присваивания.

  

Читать учебники - полезно. 

 Оба пишете кривой говнокод. Передавайте переменные в функцию явным образом и возвращайте результат:  

```
def my_func(x):
    ...
    return result
```
  

[https://ru.wikipedia.org/wiki/Чистота\_функции](https://ru.wikipedia.org/wiki/%D0%A7%D0%B8%D1%81%D1%82%D0%BE%D1%82%D0%B0_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%B8)