函数
2018-04-16 19:39 邪月三猩 阅读(146) 评论(0) 收藏 举报函数的return
- 遇到return,结束函数。
- 给函数的调用者(执行者)返回值。无 return 返回None,return后面不写返回值或者写None 返回None,return 返回单个数,return 返回多个数,将多个数放在元组中返回。
函数的参数
- 位置参数。 形参与实参必须一一对应,按顺序传入。
- 以关键字的方式传入参数。必须一一对应,不分顺序。fun1(a=1,b=a)
- 默认参数,无论是形参还是实参必须放在位置参数的后面。
- 动态参数 *args,**kwargs 万能参数。在形参中是聚合参数的作用,在实参中是解包的作用。
- 最终的参数顺序是:位置参数,*args,默认参数,**kwargs
函数的作用域
- 全局作用域:全局名称空间,内置名称空间。
- 局部作用域:局部名称空间
- 变量与值的加载顺序:内置名称空间 ----> 全局名称空间----> 局部名称空间(函数执行时)
- 变量与值的取值顺序:局部名称空间 ---> 全局名称空间 ----> 内置名称空间
函数名的特性
- 可以互相赋值。
- 函数名可以当成函数的参数
- 可以当成容器类数据类型的参数
- 函数名可以当成函数的返回值
函数的默认参数
在 python 中,类型属于对象,变量是没有类型的:
a=[1,2,3]
a="Runoob"
以上代码中,[1,2,3] 是 List 类型,"Runoob" 是 String 类型,而变量 a 是没有类型,a仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。
在 python 中,strings, tuples, 和 numbers 是不可变类型,而 list,dict 等则是可变类型。
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,而是a指向了10。
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
不可变类型:如 整数、字符串、元组。如fun(a),传递的只是a的copy,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
可变类型:如 列表,字典。如 fun(la),则是将 la 的引用传过去,修改后fun外部的la也会受影响
结果如下:
传入函数的和函数返回的都是同一个对象的引用。
故:x.append会修改默认参数。
函数的默认参数应该是不可变类型的。
解决方案,使用None 作为默认值,并在函数体中增加一个对默认值的检查。
例:
上面的例子是错误的。如果传入的b是空的字符串,列表,元组,0等,任意一种bool值等于False的数据类型。也会让b=[]。
完美的解决方法是:
object()是一个内存地址,独特的私有实例,可以用这个特殊值判断用户是否提供了参数。
函数中的闭包
- 闭包: 内层函数对外层函数非全局变量的引用,叫做闭包
- 闭包的好处:如果python 检测到闭包,,函数的局部作用域不会随着函数的结束而结束
- 判断是不是闭包print(内层的函数名.__closure__)
浙公网安备 33010602011771号