2016-08-20 2 views
0

(Это все на Python 3.5.2)Python постижения в вызовах функций (PEP 448)

В нижней части PEP 448, я вижу:

постижений в индексных скобках вызовов функций, такие как f(x for x in it) , уже действуют.

Это интригующе. Если я определяю следующие функции:

def f(a, b, c): 
    return a + b + c 

то, что формулировка заставляет меня думать, что f(thing for thing in [1, 2, 3]) == 6. Но на самом деле, я получаю:

>>> f(thing for thing in [1, 2, 3]) 
TypeError: f() missing 2 required positional arguments: 'b' and 'c' 

т.е. все выражение генератора, переданного в качестве a.

Так что же это предложение в PEP 448 означает? Просто вы можете передать выражение генератора в качестве аргумента?

ответ

1

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

foo(x for x in range(10)) 

в основном эквивалентен:

genexp = (x for x in range(10)) # parentheses are necessary here 
foo(genexp) 

Вы все еще нуждаетесь в круглых скобках при определении выражения генератора, если есть другие аргументы, которые вы передаете в вызов функции (например, foo(w, (x for x in range(10)), y, z) , где второй аргумент является генераторным выражением x 's).

PEP упоминал попутно, что дальнейшее расширение синтаксиса распаковки может быть запутанным в этом контексте. Если новый вид генераторного выражения (*x for x in nested) является законным (он не является частью окончательного PEP, но рассматривается как некоторое время), как должно работать foo(*x for x in nested)? Будет ли это эквивалентно foo((*x for x in nested)) (вызов с одним выражением генератора, включающим новое «сглаживание» *), или это будет означать foo(*(x for x in nested)) (что законно сейчас)?

4

Это заявление означает только то, что в pre-PEP мир f(x for x in it) уже был действительным и передал выражение генератора в качестве аргумента первой функции.

Чтобы сделать ваш пример работы, вам необходимо явно распаковать генератор, как показано в примерах PEP.

f(*(thing for thing in [1, 2, 3])) # returns 6 
0

Что происходит в том, что на линии f(thing for thing in [1, 2, 3]) вы передаете только первый аргумент, который является генератором. Аргументы b и c отсутствуют.

Также проверьте следующую часть PEP:

Однако, не ясно, было ли это лучшее поведение или если он следует распаковать в аргументы вызова ф. Так как это , вероятно, будет запутанным и имеет лишь очень незначительную полезность, это не , включенный в этот ОПТОСОЗ. Вместо этого они будут использовать SyntaxError и с использованием явных скобок.

0

На самом деле f(x for x in it) не новая функция, которая введена PEP 448 но PEP 289. Отмечены не все функции, которые обсуждались в PEP 448, реализованы в Python 3.5. "Variations" section упомянуто в вопросе не будет реализован:

Поскольку это может привести к путанице и только очень маргинальной полезности, она не включена в этот PEP. Вместо этого они будут вызывать SyntaxError, и вместо этого следует использовать выражения с явными скобками .

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