В чем разница между 'r = yield n' и 'r = (yield n)'? - PullRequest
2 голосов
/ 09 апреля 2019

Я изучал сопрограмму и попробовал учебник, я нашел этот код.

>>> def g(n):
...     while n >= 0:
...         r = (yield n)
...         if r:
...             n = r
...         else:
...             n -= 1

Я спросил себя, почему было r = (yield n), затем я изменил код, как показано ниже,

>>> def f(n):
...     while n >= 0:
...         r = yield n
...         if r:
...             n = r
...         else:
...             n -= 1
...
>>>

После этого я догадался, что при вызове send(value), r = yield n вернет значение, а r = (yield n) вернет кортеж, например (value,).

Итак, я тестировал код отдельно, результат:

>>>
>>> gc = g(5)
>>> gc.send(None)
5
>>> type(gc.send(4))
<class 'int'>
>>>

>>> fc = f(5)
>>> fc.send(None)
5
>>> fc.send(4)
4
>>> type(fc.send(4))
<class 'int'>

Оба результата имели тип int, а не тип кортежа. Я действительно запутался, в чем разница между двумя кодами? Казалось, нет никакой разницы.

Ответы [ 3 ]

2 голосов
/ 09 апреля 2019

Нет разницы, которую вы можете проверить непосредственно с помощью парсера :

>>> source1 = "r = (yield n)"
>>> source2 = "r = yield n"
>>> import ast
>>> ast.dump(ast.parse(source1))
"Module(body=[Assign(targets=[Name(id='r', ctx=Store())], value=Yield(value=Name(id='n', ctx=Load())))])"
>>> ast.dump(ast.parse(source2))
"Module(body=[Assign(targets=[Name(id='r', ctx=Store())], value=Yield(value=Name(id='n', ctx=Load())))])"

Вы также можете прийти к такому же выводу более окольным путем, проверив разборка из f и g.

Непустые кортежи требуют запятых, см. Когда требуются скобки вокруг кортежа?

1 голос
/ 09 апреля 2019

Казалось, что никакой разницы нет вообще.

Вы правы - разницы нет вообще.

Назначение r = (yield n) просто имеет некоторыеизбыточные парены.Это очень похоже на назначение four = 1 + (1 + 1) + 1;Парены ничего не меняют.

Если вы хотите 1-кортеж, используйте запятую:

>>> r = 6,
>>> r
(6,)

Не стесняйтесь приставлять к паренсу, как (6,), если вы чувствуетеВы должны обратить внимание на тот факт, что ваше выражение является кортежем.

0 голосов
/ 09 апреля 2019

Разницы нет. Скобка говорит переводчику сначала вычислить это утверждение. Когда интерпретатор читает r = yield n, он сначала вычислит yield n, а затем назначит его для r. Сначала он уже вычисляет yield n, поэтому в скобках нет необходимости. Если вы хотите сделать его кортежем, вы можете использовать этот код r = (yield n,)

...