Классы, вложенные в функции и поиск атрибутов - PullRequest
4 голосов
/ 05 августа 2009

Следующее работает хорошо, т.е. не выдает никаких ошибок:

def foo(arg):
    class Nested(object):
        x = arg

foo('hello')

Но следующее бросает исключение:

def foo(arg):
    class Nested(object):
        arg = arg # note that names are the same

foo('hello')

Traceback:

Traceback (most recent call last):
  File "test.py", line 6, in <module>
    foo('hello')
  File "test.py", line 3, in foo
    class Nested(object):
  File "test.py", line 4, in Nested
    arg = arg
NameError: name 'arg' is not defined

Я не могу понять причину такого поведения. Кто-нибудь может объяснить?

Ответы [ 3 ]

5 голосов
/ 05 августа 2009

Свойство arg скрывает аргумент функции arg (внутренняя область видимости)

def foo(arg):
    class Nested(object):
        arg = arg # you try to read the `arg` property which isn't initialized


Вы получите ту же ошибку, если вы введете i = i в окне интерпретатора без инициализации переменной i.

3 голосов
/ 05 августа 2009

Это связано с правилами Python:

def foo(arg): # (1)
    class Nested(object):
        arg = arg # (2)

(2) определяет новое имя 'arg' в пространстве имен класса ', которое скрывает значение другого' arg 'во внешнем пространстве имен (1).

Тем не менее, (2) не требуется, и следующее полностью верно:

def foo(arg):
    class Nested(object):
        def message(self):
            print arg
    return Nested()

nested = foo('hello')
nested.message()

(отпечатки hello)

3 голосов
/ 05 августа 2009

Если вы попытаетесь присвоить переменную внутри функции, Python предполагает, что эта переменная является локальной для этой функции. Поэтому, пытаясь присвоить arg собственному значению, вы неявно объявляете его локальной переменной.

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