2015-06-16 2 views
2

Источник: Обучение питона по марке Лутцсостояние удержания для классов и закрытия

область содержания: страница # 503

классов против закрытия: Он утверждает, что "классы могут показаться лучше на государственном удержании, потому что они делают их память более явна с назначением атрибутов.

функции закрытия часто обеспечивают более легкую и жизнеспособную альтернативу, когда сохранение состояния является единственной целью. Они обеспечивают локальное хранение для каждого вызова для данных, требуемых одной вложенной функцией.

Что означает государственная рента и как сделать память более явной с назначением атрибутов?

Может ли кто-нибудь представить пример, который доказывает более легкий вес для закрытия в случае сохранения состояния и объясняет, что такое локализованное хранилище для данных в контексте одной вложенной функции?

ответ

4

Это простое замыкание:

def make_counter(start=0): 
    count = start - 1 
    def counter(): 
     nonlocal count # requires 3.x 
     count += 1 
     return count 
    return counter 

Вы называете это так:

>>> counter = make_counter() 
>>> counter() 
0 
>>> counter() 
1 
>>> # and so on... 

Как вы можете видеть, он отслеживает, сколько раз она была вызвана. Эта информация называется «состояние». Это «локализованное состояние за вызов», потому что вы можете сделать сразу несколько счетчиков, и они не будут мешать друг другу. В этом случае состояние сохраняется (почти) неявно, основываясь на замыкании, сохраняя ссылку на переменную count из ее охватывающей области. С другой стороны, класс будет более явным:

class Counter: 
    def __init__(self, start=0): 
     self.count = start - 1 
    def __call__(self): 
     self.count += 1 
     return self.count 

Здесь государство явно присоединен к объекту.

+0

Я попробовал пример закрытия в интерактивной оболочке, он работал нормально, но когда я пытаюсь выполнить counter(), я получаю Typeerror: объект «NoneType» не может быть вызван. Также почему вы отметили нелокальное значение count ... мы применяем правило LEGB для переменных области? – Praneeth

+0

@Praneeth: Я исправил объект NoneType. Если бы мы не использовали 'nonlocal', пример был бы незаконным, так как он попытался бы увеличить локальную переменную, которая еще не существует. – Kevin

+0

это работает сейчас. Чтобы заключить, что выражение через классы выглядит более прямолинейно, чем замыкание в терминах количества строк, это означает, что мы сохраняем больше данных в кеше для классов, чем функции закрытия!? – Praneeth

Смежные вопросы