Сегодня я наткнулся на кусок кода, который выглядит так:
class ClassName(object):
def __init__(self):
self._vocabulary = None
def vocabulary(self):
self._vocabulary = self._vocabulary or self.keys()
return self._vocabulary
Что именно делает линия self._vocabulary = self._vocabulary or self.keys()
?
Строка, подобная этой:
self._vocabulary = self._vocabulary or self.keys()
Это то, что называется ленивой инициализацией, когда вы извлекаете значение в первый раз, когда оно инициализируется. Поэтому, если он никогда не был инициализирован, self._vocabulary
будет None
(потому что метод __init__
установил это значение), что привело к оценке второго элемента or
, поэтому self.keys()
будет выполняться, назначая возвращающее значение до self._vocabulary
, тем самым инициализируя его для будущих запросов.
Когда второй раз vocabulary
вызывается self._vocabulary
не будет None
, и он сохранит это значение.
__init__
которая устанавливает self._vocabulary
в None
, это не происходит автоматически.
В двух словах, если self._vocabulary
вычисляет логическое значение false (например, если оно None
, 0
, False
и т.д.), то оно будет заменено на self.keys()
.
Оператор or
в этом случае возвращает какое-либо значение в логическое значение true.
Кроме того, ваш код должен выглядеть примерно так:
class Example(object):
def __init__(self):
self._vocabulary = None
def vocabulary(self):
self._vocabulary = self._vocabulary or self.keys()
return self._vocabulary
def keys(self):
return ['a', 'b']
ex = Example()
print ex.vocabulary()
ex._vocabulary = 'Hi there'
print ex.vocabulary()
The or operator in this case, returns whichever value evaluates to a logical true.
- Это немного вводит в заблуждение. Если self._vocabulary
оценивается как False
то self.keys()
выполняется и используется для назначения независимо от того, оценивается ли он как True
или False
. См. Stackoverflow.com/questions/1452489/… для объяснения того, как вещи оцениваются в логических выражениях.
Сложно сказать, что код не будет работать по ряду причин. Предположим, однако, я бы сказал, что похоже, что это будет оценено как логическое выражение, self._vocabulary
будет оцениваться False
python как type None
, а self.keys()
- это метод, который (надеюсь) вернется что-то, что нужно оценить. Тогда это просто логическое ИЛИ между ними, и результат попадает в self._vocabulary
.