Это сообщение немного длинное со многими примерами, но я надеюсь, что он поможет мне и другим людям лучше понять всю историю переменных и найти атрибут в Python 2.7.Как ссылки на переменные разрешены в Python
Я использую условие PEP 227 (http://www.python.org/dev/peps/pep-0227/) для кодовых блоков (такие, как модулей, определения класса, определения функций и т.д.) и привязок переменных (например, назначений, деклараций аргументов, класса и функций декларация, для петель и т.д.)
Я использую переменные термины для имен, которые могут быть вызваны без точки, и атрибуты для имен, которые должны быть квалифицированы с именем объекта (например, obj.x для атрибут x объекта obj).
Есть три области применения в Python для всех кодовых блоков, но функции:
- Местного
- Global
- Builtin
Есть четыре блока в Python для функций только (в соответствии с PEP 227):
- Местные
- Ограждающие функции
- Global
- Builtin
Правило для переменной, чтобы связать его и найти его в блоке довольно просто:
- обязывающих переменной к объекту в блоке делает эту переменную локальной для этого блока, если только переменная не объявлена глобальной (в этом случая, переменный принадлежит к глобальной области)
- ссылка на переменный ищутся с использованием правил LGB (локальная, глобальными, встроенным) для всех блоков, но функции
- ссылки на переменный ищутся используя правило LEGB (локальное, , охватывающее, глобальное, встроенное) только для функций.
Сообщите мне об этом решении и дайте множество примеров, например, . Для каждого примера я дам свое понимание. Пожалуйста, исправьте меня, если я ошибаюсь. В последнем примере я не понимаю результат .
Пример 1:
x = "x in module"
class A():
print "A: " + x #x in module
x = "x in class A"
print locals()
class B():
print "B: " + x #x in module
x = "x in class B"
print locals()
def f(self):
print "f: " + x #x in module
self.x = "self.x in f"
print x, self.x
print locals()
>>>A.B().f()
A: x in module
{'x': 'x in class A', '__module__': '__main__'}
B: x in module
{'x': 'x in class B', '__module__': '__main__'}
f: x in module
x in module self.x in f
{'self': <__main__.B instance at 0x00000000026FC9C8>}
Там нет вложенной возможности для классов (правило LGB) и функции в класс не может получить доступ к атрибутам класса без использования квалифицированного имени (self.x в этом примере). Это хорошо описано в PEP227.
Пример 2:
z = "z in module"
def f():
z = "z in f()"
class C():
z = "z in C"
def g(self):
print z
print C.z
C().g()
f()
>>>
z in f()
z in C
Здесь переменные в функциях ищутся с помощью правила LEGB, но если класса находится в пути, аргументы класса пропускается. И здесь это то, что объясняет PEP 227.
Пример 3:
var = 0
def func():
print var
var = 1
>>> func()
Traceback (most recent call last):
File "<pyshell#102>", line 1, in <module>
func()
File "C:/Users/aa/Desktop/test2.py", line 25, in func
print var
UnboundLocalError: local variable 'var' referenced before assignment
Мы ожидаем, что с динамическим языком, таких как питон, что все решена динамически. Но это не относится к функциям. Локальные переменные определяются во время компиляции. PEP 227 и http://docs.python.org/2.7/reference/executionmodel.html описывают эту поведение на этот путь
«Если имя привязки операция происходит в любом месте в пределах блока кода, все использования имени внутри блока трактуются как ссылки на текущего блока.»
Пример 4:
x = "x in module"
class A():
print "A: " + x
x = "x in A"
print "A: " + x
print locals()
del x
print locals()
print "A: " + x
>>>
A: x in module
A: x in A
{'x': 'x in A', '__module__': '__main__'}
{'__module__': '__main__'}
A: x in module
Но здесь мы видим, что это утверждение в PEP227 «Если имя связывание операции происходит в любом месте в пределах блока кода, все виды использование имени в пределах блока, рассматривается в качестве ссылок к текущему блоку. " неверно, если блок кода является классом. Более того, для классов кажется , что привязка локального имени не выполняется во время компиляции, но во время выполнения с использованием пространства имен классов. В этом отношении PEP227 и модель исполнения в документе Python вводит в заблуждение, а для некоторые части ошибочны.
Пример 5:
x = 'x in module'
def f2():
x = 'x in f2'
def myfunc():
x = 'x in myfunc'
class MyClass(object):
x = x
print x
return MyClass
myfunc()
f2()
>>>
x in module
мое понимание этого кода заключается в следующем. Команда x = x сначала ищет объект правой рукой x выражения ссылается на. В этом случае объект просматривается локально в классе, затем , следуя правилу LGB, он просматривается в глобальной области, которая равна строке «x в модуле». Затем локальный атрибут x для MyClass составляет , созданный в словаре классов, и указывает на строковый объект.
Пример 6:
Теперь вот пример, который я не могу объяснить. Это очень близко к примеру 5, я просто изменяю локальный атрибут MyClass от x до y.
x = 'x in module'
def f2():
x = 'x in f2'
def myfunc():
x = 'x in myfunc'
class MyClass(object):
y = x
print y
return MyClass
myfunc()
f2()
>>>
x in myfunc
Почему в этом случае х ссылка в MyClass ищется в самой внутренней функции ?
Очень сложно сказать, что должно происходить в последних нескольких примерах с отступом так, как оно есть - не могли бы вы исправить это? (Помните, что 4-сегментный отступ создает блок кода - каждое пространство после этого показано как пробел в образце кода). –
Это похоже на очень интересный вопрос, но, пожалуйста, исправьте углубление. – thefourtheye
@SeanVieira благодарит за замечание. У меня было много вкладок вместо пробелов. Теперь это исправлено. – user3022222