Найти - Пользователи
Полная версия: UnboundLocalError
Начало » Python для новичков » UnboundLocalError
1 2 3 4 5
pasaranax
UsCr
Только в ней, но не в функциях описанных в ней?
и в функциях описанных в ней, они ведь тоже в ней находятся )

UsCr
У меня остался ещё вопрос: как в данном случае обойтись без global?
import random
rand = random.randint
randch = random.choice
arr = []

#generiruem massiv
def generate(KolSymb):

KolDvoetoch = 0 # !!!

def HowMuch():
j = rand(0,100)
if j%2==0: KolDvoetoch = 2
else: KolDvoetoch = 1

def GetDvoetoch():
if KolDvoetoch>0:
KolDvoetoch = KolDvoetoch-1
k = ":"
else: k = randch("abcdefghigklmnopqrstuvwxyz")


k = ""
HowMuch()

for i in range(KolSymb+1):
j = rand(0,10)
if j==0: k = randch("abcdefghigklmnopqrstuvwxyz")
else: GetDvoetoch()
arr.append(k)
print arr
UsCr
pasaranax
import random
rand = random.randint
randch = random.choice
arr = []

#generiruem massiv
def generate(KolSymb):

KolDvoetoch = 0 # !!!

def HowMuch():
j = rand(0,100)
if j%2==0: KolDvoetoch = 2
else: KolDvoetoch = 1

def GetDvoetoch():
if KolDvoetoch>0:
KolDvoetoch = KolDvoetoch-1
k = ":"
else: k = randch("abcdefghigklmnopqrstuvwxyz")


k = ""
HowMuch()

for i in range(KolSymb+1):
j = rand(0,10)
if j==0: k = randch("abcdefghigklmnopqrstuvwxyz")
else: GetDvoetoch()
arr.append(k)
print arr
Третье сверху сообщение в теме. Я уже пробовал делать так. Не работает. Кстати, вообще код рабочий? Может у меня с софтом беда? Ставил IDLE из репозитоия. Под виндой аналогичная фигня выходит.
pasaranax
Что-то я тоже запутался. Получается, питон не совсем очевидно себя ведет в этом случае. Он смотрит вперед выполняемой строки. Вот пример:
b = "hello"
def a():
print b
b = "world"
a()
Он вызывает такую же ошибку на строке ‘print b’, но если убрать следующую за ней строку ‘b = “world”’, то все в порядке. То есть в начале выполнения функции питон уже знает, что мы где-то в ней переопределили бывшую глобальную переменную своей локальной и не дает ее использовать до этого момента.
Кстати, изменить глобальную b внутри функции a он не даст, так что твой подход не будет работать, передавай во вложенные функции KolDvoetoch в качестве параметра, и не надо будет использовать global.
Андрей Светлов
Нет. Все как раз очень очевидно.
Модули (а также классы и функции) - компилируются в байткод перед исполнением. Определение не совсем строгое - но сойдет.
>>> import dis
>>> b = "Hello"
>>> def a():
... print b
...
>>> dis.dis(a)
2 0 LOAD_GLOBAL 0 (b)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
Т.е. b в данном случае - глобальное имя, потому что не было присваивания (инициализации) внутри функции a.
То же самое с явным заданием global
>>> def a():
... global b
... print b
...
>>> dis.dis(a)
3 0 LOAD_GLOBAL 0 (b)
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
А теперь - с инициализацией
>>> def a():
... print b
... b = 'world'
...
>>> dis.dis(a)
2 0 LOAD_FAST 0 (b)
3 PRINT_ITEM
4 PRINT_NEWLINE

3 5 LOAD_CONST 1 ('world')
8 STORE_FAST 0 (b)
11 LOAD_CONST 0 (None)
14 RETURN_VALUE
LOAD_FAST/STORE_FAST - опкоды для доступа к локальной переменной. Которой в начале еще нет.

С вложенными функциями - отдельная тема. Говоря коротко, питон смотрит в вызываемушую функцию перед тем, как смотреть в global scope. Если имя есть - оно помещается в func_closure и используется.
>>> def f():
... v = 'Hello'
... def g():
... print v
...
>>> dis.dis(f)
2 0 LOAD_CONST 1 ('Hello')
3 STORE_DEREF 0 (v)

3 6 LOAD_CLOSURE 0 (v)
9 BUILD_TUPLE 1
12 LOAD_CONST 2 (<code object g at 025802F0, file "<interactive input>", line 3>)
15 MAKE_CLOSURE 0
18 STORE_FAST 0 (g)
21 LOAD_CONST 0 (None)
24 RETURN_VALUE
>>>
Обратите внимание на LOAD_CLOSURE
В “классическом” Python 2.x нет способа переопределить имя для closure. Т.е. в g() нельзя написать v=3. Это будет распознано как создание локальной переменной. Стандартный способ обхода - использовать списки v = , затем v = ‘world’
В Python 3.x появилось новое слово nonlocal для этих целей.
>>> def f():
v = "Hello"
def g():
nonlocal v
print (v)
v = "world"
print (v)
return g

>>> dis.dis(f)
2 0 LOAD_CONST 1 ('Hello')
3 STORE_DEREF 0 (v)

3 6 LOAD_CLOSURE 0 (v)
9 BUILD_TUPLE 1
12 LOAD_CONST 2 (<code object g at 0x027BC698, file "<pyshell#14>", line 3>)
15 MAKE_CLOSURE 0
18 STORE_FAST 0 (g)

8 21 LOAD_FAST 0 (g)
24 RETURN_VALUE
>>> dis.dis(f())
5 0 LOAD_GLOBAL 0 (print)
3 LOAD_DEREF 0 (v)
6 CALL_FUNCTION 1
9 POP_TOP

6 10 LOAD_CONST 1 ('world')
13 STORE_DEREF 0 (v)

7 16 LOAD_GLOBAL 0 (print)
19 LOAD_DEREF 0 (v)
22 CALL_FUNCTION 1
25 POP_TOP
26 LOAD_CONST 0 (None)
29 RETURN_VALUE
Тема не совсем тривиальная - так что спрашивайте.
UsCr
Так… А при передаче глобольной переменной в функцию в качестве параметра он даст её изменить? Она при этом не перестанет быть глобальной?
UsCr
Вот оно:
import random
rand = random.randint
randch = random.choice
arr = []

def generate(KolSymb):
def proced():
def GetDvoetoch(KolDvoetoch):
if KolDvoetoch>0:
KolDvoetoch = KolDvoetoch-1
symb = ":"
else: symb = randch("abcdefghigklmnopqrstuvwxyz")
return symb
j = rand(0,100)
if j%2==0: KolDvoetoch = 2
else: KolDvoetoch = 1
j = rand(0,1)
if j==0: k = GetDvoetoch(KolDvoetoch)#KolDvoetoch)
else: k = randch("abcdefghigklmnopqrstuvwxyz")
return k

for i in range(KolSymb+1):
arr.append(proced())
print arr
Оно работает, но не так, как нужно. Сейчас выдаётся последовательность вида: , хотя должно быть не более двух двоеточий. Значит, опять не всё в порядке с KolDvoetoch(именно она контролирует количество двоеточий)
Dimka665
import random
from UserString import MutableString

alphabet = "abcdefghigklmnopqrstuvwxyz"
m = MutableString(''.join(random.choice(alphabit) for i in xrange(random.randint(10,20))))
m += ';' * random.randint(1,2)
random.shuffle(m)
Ed
UsCr
Оно работает, но не так, как нужно.
Попробуйте решить задачу по частям:
1. Сгенерите список.
2. Вставьте двоеточия в случайные места.
UsCr
Ох,да… Декомпозиция, мать наша…
Тема, я думаю закрыта. Остальное уже выходит за рамки.
Благодарю за помощь.
Ed
UsCr
Ох,да… Декомпозиция, мать наша…
Тема, я думаю закрыта. Остальное уже выходит за рамки.
Интересно было бы увидеть ваше решение.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB