Ruby-подобный выход в Python 3 - PullRequest
0 голосов
/ 08 марта 2019

Все,

Мне действительно нравится, как Руби уступает.

def wrap_print
  puts 'A'
  yield
  puts 'C'
end

wrap_print do
  puts 'B'
end

> A
> B
> C

Я не нашел способа подражать этому в Python.У кого-нибудь есть идеи?

Ответы [ 2 ]

2 голосов
/ 09 марта 2019

yield просто передает управление блоку.Другими словами, он вызывает блок.

В Python функции являются первоклассными, поэтому нет необходимости различать различные типы вызываемых объектов, как это делает Ruby (метод, блоки и процессы).Таким образом, эквивалент Python для уступки блоку - это просто вызов функции:

def wrap_print(f):
  print('A')
  f()
  print('C')

def _():
  print('B')

wrap_print(_)

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

Например, в этом случае вам не нужна именованная функция:

def transform(list, transformer):
  newlist = []
  for el in list:
    newlist.append(transformer(el))
  return newlist

transform([1, 2, 3], lambda el: el * 2)
#>>> [2, 4, 6]
0 голосов
/ 08 марта 2019

Я сразу понял это. Сохранение моего результата в качестве полного примера.

from contextlib import contextmanager

@contextmanager
def wrap_print():
  print('A')
  yield
  print('C')

with wrap_print():
  print('B')

Если вы хотите передать значение в блок.

from contextlib import contextmanager

@contextmanager
def wrap_print():
    print('A')
    yield 'B'
    print('C')

with wrap_print() as foo:
    print(foo)
...