Вопрос

I'm a beginner at Python, trying to understand function arguments and their types and orders.

I tried to experiment a little with the different kinds of argument and here's my experiment

def main():
    test_a(2, 33, 44)
    test_b(2, 33)
    test_c(2)
    ## test_d(2,,44) **Produces Invalid syntax**

    test_e(2,33,44,55,66)
    test_f(2, 44,55,66, y = 44)

    test_g(2, 33, 44,55,66, rofa = 777, nard = 888)
    ##test_h(2, 33, foo = 777, boo = 888, 44,55,66)  **Invalid Syntax in Function definition
    ##test_l(2, 44,55,66 ,  foo= 777, boo = 888, y  = 900) **Invalid Syntax in Function definition
    test_m(2, 44,55,66 , y = 900, foo=77777 , boo = 88888)

#############################################################
## NO optional arguments
def test_a(x,y,z):
    print("test_a : x = {}, y = {}, z = {} ".format(x ,y ,z))

## One optional argument at the end
def test_b(x, y, z = 22):
    print("test_b : x = {}, y = {}, z = {} ".format(x ,y ,z))

## TWO optional arguments at the end
def test_c(x, y = 11, z = 22):
    print("test_c : x = {}, y = {}, z = {} ".format(x ,y ,z))

## ONE optional argument at the middle
## Produces Non-default argument follows default argument
#### **** DEFAULT ARGUMENTS MUST COME AT THE END **** ####
## def test_d(x, y = 11, z):
##    print("test_d : x = {}, y = {}, z = {} ".format(x ,y ,z))

#################################################################

## NO optional argument + One List argument
def test_e(x, y, *args):
    print("test_e : x = {}, y = {} ||".format(x, y), end= " ")
    for i in args :
        print(i)

## One optional argument + One list argument
def test_f(x, *args , y = 5):
    print("test_f : x = {}, y = {} ||".format(x, y), end= " ")
    for i in args :
        print(i)

################################################################

## No optional argument, one list, one keyword arguments
def test_g(x,y,*args, **kwargs):
    print(x, y)
    for i in args:
        print(i)

    for i, v in kwargs.items():
        print(i, v)

## **kwargs befor *args produces syntax error !!!
##def test_h(x,y, **kwargs, *args):
##    print(x, y)
##    for i in args:
##        print(i)
##
##    for i, v in kwargs.items():
##        print(i, v)

## **kwargs befor optional argument produces syntax error !!!
##def test_l(x,*args,**kwargs, y = 5):
##    print(x, y)
##    for i in args:
##        print(i)
##
##    for i, v in kwargs.items():
##        print(i, v)
##    

## One optiona, list and keyword arguments
def test_m(x,*args,y = 5, **kwargs):
    print(x, y)
    for i in args:
        print(i)

    for i, v in kwargs.items():
        print(i, v)


if __name__ == "__main__":
    main()

I really understood most of things after this experiment. But there's one issue that i can't get inside my head.

In the function definition in test_h and test_m where **kwargs are defined before optional argument and list argument, when i run the program, even if i didn't use that function, just defined it.. It produces Syntax Error .. I'd be grateful to know why is this happening ?

Thanks.

Это было полезно?

Решение

Keyword arguments have to be the final arguments passed to a function. Read up on it here. Parameters like **kwargs must be the last parameter in a function signature (as detailed on that page in the docs). From the documentation:

When a final formal parameter of the form **name is present, it receives a dictionary (see Mapping Types — dict) containing all keyword arguments except for those corresponding to a formal parameter.

The reason your code raises a SyntaxError even if you don't use that function is that if you violate this rule, Python can't even complete the function definition since the signature you're trying to give it is illegal.

Другие советы

*args and **kwargs must be the last arguments specified (in that order!); the reason is that they're essentially "catch-alls" that match arguments passed to the function that don't match the specific arguments listed beforehand, so having them listed before specific arguments is ambiguous.

For example, test_m above must be specified as

def test_m(x, y=5, *args, **kwargs):
    ...
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top