1. def func( ...... ): #默认情况下,参数值和参数名称是按函数声明中定义的顺序匹配起来的。
  2. '''
  3. 函数说明 #文档字符串,见下面说明,python有潜规则
  4. '''
  5. ...... #进入函数提后,会有一个存储函数局部变量的新符号表
  6. #变量的查找首先会在这个局部符号表中查找,然后是外层局部符号表,
  7. #再是全局局部符号表,最后是内置名称符号表。有点类似Lua的环境表。
  8. return ...... #没有return值,就返回None

参数传递

  1. def changeVal( arg ):
  2. #传入参数的过程:相当于生成一个新变量(指针),指向传入的变量指向的对象。
  3. #类比C++的指针传递,本质就是值传递,值就是对象的地址。
  4. arg = 2 #arg = &Number(2),改变的只是arg的指向。
  5. arg[0] = 1 #如果arg指向的对象可修改比如List,则通过arg可修改传入的对象
  6. #最终效果就是函数内部可修改传入的对象,但对象必须是可修改类型。
  7. return;
  8. num = 1 #void *num = &Number(1)
  9. lst = [1]
  10. changeVal(num) #void *arg = num,arg和num都指向Number(1)
  11. changeVal(lst) #void *arg = lst,arg和num都指向lst,通过arg修改了lst,num看起来也跟着改变。
  12. print(num) #输出:1

参数匹配

  • key匹配
  • 顺序匹配 ```python def fuckme(shit1, shit2):

    python中,参数名字是实际意义的,准备的应该叫参数的key(关键字)。

    关键字参数kwarg

    key匹配:如传入的参数key为shit1,则值传入到第一个参数位置。

    传入的参数如果有key,则后续都必须有key。

    这种带key的参数,我们将关键字参数kwarg

    位置参数

    顺序匹配:默认匹配方式,没有key就按这种方式。

    从shit1开始,从左往右依次填充,

    注意一定是从shit1开始,也就是第一个参数开始。

    pass

fuckme(1) #没有key,按顺序匹配 fuckme(shit1=1) #key为shit1,按key匹配 fuckme(shit3=1) #key为shit3,按key匹配,但没有找到,报错。 fuckme(shit1=1,2) #错误:后续都必须有key fuckme(1, shit1=1) #错误,shit1参数有多个值匹配。 fuckme(1, shit2=1) #正确

  1. <a name="NBZyU"></a>
  2. ## 默认参数
  3. 规则和C++类似。
  4. ```python
  5. def fuckme(shit1, shit2=2)
  6. #如果一个参数有默认值,则后续都必须有默认值
  7. #注意,一个函数的所有调用都共享一份默认值,见下面例子理解。
  8. pass;
  9. fuckme(1) #shit1=1,shit2=2
  10. fuckme(shit1=1) #shit1=1,shit2=2
  11. fuckme(1, 3) #shit1=1,shit2=3
  12. #shit2的[]将被所有函数调用共享
  13. def fuckme(shit1, shit2=[]):
  14. shit2.append(shit1)
  15. print(shit2)
  16. fuckme(1) #[1]
  17. fuckme(2) #[1, 2]
  18. fuckme(3) #[1, 2, 3]
  19. #如何不共享默认值?
  20. def fuckme(shit1, shit2=None):
  21. if shit2 is None:
  22. shit2 = [];
  23. shit2.append(shit1)

可变参数列表

*args

  1. def fuckme(arg1..., *args, argn...):
  2. #args是一个列表/元组,存储的是位置参数,argn...可以没有,或者必须是kwarg关键字参数
  3. #*args相当于解包args,类似Lua的unpack一个table。
  4. for arg in var_list:
  5. pass
  6. pass
  7. def fuckme(*args):
  8. pass
  9. fuckme( 10 )
  10. fuckme( 70, 60, 50 )

**kwargs

  1. def fuckme(arg1..., **kwargs):
  2. #kwargs是一个dict字典,存储的是所有关键字参数,除了与已有形参匹配了的关键字参数。
  3. #可以和*args组合使用,*args必须在**kwargs的前面。
  4. for key in kwargs:
  5. print key, kwargs[key]
  6. ################例子1
  7. def fuckme(shit1, shit2, **kwargs):
  8. print shit1, shit2
  9. print("-" * 10)
  10. for key in kwargs:
  11. print key, kwargs[key]
  12. fuckme(1, shit2=2,bitch=3,fuck=4);
  13. # 1, 2
  14. #-----------
  15. # bitch, 3
  16. # fuck, 4
  17. ################例子2
  18. def fuckme(shit1, shit2, *args, **kwargs):
  19. print shit1, shit2
  20. print("-" * 10)
  21. for arg in args:
  22. print(arg)
  23. print("-" * 10)
  24. for key in kwargs:
  25. print key, kwargs[key]
  26. fuckme(1, 2, 3, 4, 5, 6, bitch=7, fucker=8)
  27. # 1, 2
  28. #-----------
  29. # 3, 4, 5, 6
  30. #-----------
  31. # bitch, 7
  32. # fucker, 8

解包参数列表:unpack

  1. #unpack场景一:列表元组中的参数,转换成位置参数
  2. def unpack_arg(arg1, arg2, arg3):
  3. print(arg1, arg2, arg3)
  4. lst = [1, 2, 3]
  5. unpack_arg(*lst) #1, 2, 3
  6. #unpack场景二:字典中的参数,转换成关键字参数
  7. def unpack_arg(arg1, arg2, arg3):
  8. print(arg1, arg2, arg3)
  9. kwargs = { "arg3":3, "arg2":2, "arg1": 1}
  10. unpack_arg(**kwargs) #1, 2, 3

匿名函数(lambda)

  1. lambda [arg1 [,arg2,.....argn]]:expression
  2. #expression必须是一个表达式,不是代码块。
  3. #且不能访问自有参数列表之外或全局命名空间里的参数。
  4. add = lambda arg1, arg2: arg1 + arg2
  5. add(1, 2)

文档字符串

  1. def my_function():
  2. """摘要描述 #摘要一般紧接在开头引号后面
  3. #摘要和详细描述之间最好空一行
  4. 详细描述1... #详细描述最好有相同缩进
  5. 详细描述2...
  6. """
  7. pass
  8. print(my_function.__doc__)
  9. #Do nothing, but document it.
  10. #
  11. # No, really, it doesn't do anything.

函数标注

  1. def f(arg1: str, arg2: str = 'arg2') -> str:
  2. #冒号后面接一个表达式,表达式会被求值,值就是标注值。
  3. #尾置形式,表示返回值的类型。
  4. print("Annotations:", f.__annotations__) #字典,key为参数key,value为标注值
  5. print("Arguments:", ham, eggs)
  6. return ham + ' and ' + eggs
  7. f('arg1')
  8. #Annotations: {'arg1': <class 'str'>, 'return': <class 'str'>, 'arg2': <class 'str'>}
  9. #Arguments: arg1 arg2
  10. #'arg1 and arg2'