2015-02-23 3 views
2

Мне интересно, почему метод класса не смотрит в свою охватывающую область, если имя не определено.Scope in Functions vs. Methods

def test_scope_function(): 
    var = 5 
    def print_var(): 
     print(var) # finds var from __test_scope_function__ 
    print_var() 


globalvar = 5 
class TestScopeGlobal: 
    var = globalvar # finds globalvar from __main__ 

    @staticmethod 
    def print_var(): 
     print(TestScopeGlobal.var) 


class TestScopeClass(): 
    var = 5 

    @staticmethod 
    def print_var(): 
     print(var) # Not finding var, raises NameError 

test_scope_function() 
TestScopeGlobal.print_var() 
TestScopeClass.print_var() 

Я ожидал бы TestScopeClass.print_var() печатать 5, так как он может читать classvar в TestScopeClass тела.

Почему это поведение? И что я должен прочитать в docs, чтобы узнать об этом.

ответ

6

Скоупс ищется as follows:

  • самый внутренний размах, который искал во-первых, содержит локальные имена
  • области действия любых вмещающих функций, которые искали, начиная с ближайшим объемлющим scope, содержит нелокальные, но также и неглобальные имена
  • следующая последняя область содержит глобальные имена текущего модуля
  • наружная сфера (поиск в прошлом) является пространство имен, содержащих встроенные именами

(подчеркивание добавлено). Классы закрывания не ищутся, потому что их нет в списке. Такое поведение преднамеренно, потому что в противном случае descriptor protocol, который, среди прочего, предоставляет аргумент self методам, не имел бы возможности стрелять.

3

Пер the Python documentation (курсив):

Объем имен, определенных в классе блока ограничена классом блока; его не распространяется на кодовые блоки методов