Я вижу, что кто-то уже указал на мой старый рецепт "назначить и установить", который сводится в простейшей версии к:
class Holder(object):
def set(self, value):
self.value = value
return value
def get(self):
return self.value
h = Holder()
...
if h.set(isBig(y)): return h.get()
Однако это было предназначено главным образом для облегчения транслитерации между Python и языками, где назначение напрямую поддерживается в if
или while
. Если у вас есть «сотни» таких проверок и возвратов в каскаде, намного лучше сделать что-то совершенно другое:
hundreds = isBig, isSmall, isJuicy, isBlah, ...
for predicate in hundreds:
result = predicate(y)
if result: return result
или даже что-то вроде
return next(x for x in (f(y) for f in hundreds) if x)
если можно получить исключение StopIteration, если предикат не удовлетворен, или
return next((x for x in (f(y) for f in hundreds) if x)), None)
, если None
- правильное возвращаемое значение, когда предикат не удовлетворен и т. Д.
Почти всегда, использование (или даже желание ;-) трюка / не-идиомы Holder
- это «запах дизайна», который предлагает искать другой и более питонский подход - тот случай, когда Holder
оправданным является именно тот особый случай, для которого я его разработал, т. е. случай, когда вы хотите сохранить тесное соответствие между кодом Python и некоторым не-Python (вы транслитерируете эталонный алгоритм в Python и хотите, чтобы он сначала работал, а затем рефакторинг его в более Pythonic форму, или вы пишете Python как прототип, который будет транслитерирован на C ++, C #, Java и т. д., как только он будет работать эффективно).