Как дефиницията foo(*, a=1) в python съответства на официалния „списък с аргументи“ в препратката към документацията?

Наскоро изучавах *args и **kwargs в python и се натъкнах, че в python 3 може да се използва голо *, както в примера от заглавието, за да се посочи, че след него не са разрешени позиционни аргументи.

Проблемът е, че не виждам как съответства на формалната дефиниция или „списък с аргументи“ в справка. Има следната дефиниция на списък с аргументи:

argument_list        ::=  positional_arguments ["," keyword_arguments]
                        ["," "*" expression] ["," keyword_arguments]
                        ["," "**" expression]
                      | keyword_arguments ["," "*" expression]
                        ["," keyword_arguments] ["," "**" expression]
                      | "*" expression ["," keyword_arguments] ["," "**" expression]
                      | "**" expression

Единственият начин, по който виждам, че е валидно, е expression да е празно, но не можах да разбера как може да се случи.

В случай, че приемем, че expression може да е празно, тогава следните дефиниции трябва да са валидни:

def foo(*)
def bar(*,**kwargs)

Тези дефиниции нямат смисъл, тъй като * изисква ключови аргументи след него.

Така че ще се радвам на всякакви пояснения по темата. какво ми липсва Или горното БНФ не е съвсем правилно?


person Phoenix    schedule 10.07.2013    source източник


Отговори (1)


Частта от граматиката, която разглеждате, описва извикванията на функцията. И гол * наистина е невалиден при извикване на функция.

граматиката на дефиницията на функцията е в друга част от езиковата справка. Тези продукции са подходящи:

parameter_list ::=  (defparameter ",")*
                    ( "*" [parameter] ("," defparameter)* ["," "**" parameter]
                    | "**" parameter
                    | defparameter [","] )
parameter      ::=  identifier [":" expression]
defparameter   ::=  parameter ["=" expression]

Обърнете внимание, че тук parameters и defparameters не са задължителни след *.

Грешката, която се оплаква от def f(*) и def f(*, **kwds), не идва от граматиката. Това е законно, що се отнася до граматиката, и се анализира успешно. Само по време на генериране на AST това се открива и маркира като грешка . Това не е единственото синтактично ограничение, което не се обработва в граматиката.

person Community    schedule 10.07.2013
comment
Благодаря ви, сега виждам какво съм пропуснал. Но не трябва ли тази дефиниция да приема последните ми два примера: def foo(*) и def bar(*, **kwargs)? С други думи, тази дефиниция не изисква гол * да бъде последван от именувани аргументи. И интерпретаторът съобщава за грешка в случай на горните примери - person Phoenix; 11.07.2013
comment
@Phoenix Добра гледна точка. Бих казал, че това определение трябва да приеме тези примери, но може би греша. Не мога да намеря нищо, което да го забранява, и в истинската, официална граматика. Може би съм забравил как да чета контекстно-свободни граматики или това е едно от ограниченията, наложени не от анализатора, а от компилатора. - person ; 11.07.2013
comment
Благодаря ти! Чудя се защо ограничението се появи в AST поколението вместо в граматиката. Предполагам, че може да бъде включено в граматиката чрез изрично написване на няколко случая, които включват * - person Phoenix; 11.07.2013