我是靠谱客的博主 飘逸香氛,最近开发中收集的这篇文章主要介绍Python:函数默认值的作用域【__defaults__】【__kwdefaults__】,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
例子:引入
def foo(abc=[]): abc.append(200) print(abc) foo() foo() 结果: [200] [200, 200]
第二次调用为什么问什么打印的是[ 200,200],而不是[ 200 ]?
- 因为函数即对象,python把函数的默认值放在了属性中,这个属性就伴随着这个函数对象的 整个生命周期,和abc这个变量没有关系,abc调用玩就消失了
- 可查看foo.__defaults__属性查看
例子:函数值的默认值是可变类型的 : [ ]
def foo(abc=[],d = 1,e=2): abc.append(200) print(abc) print(foo(),id(foo)) print(foo.__defaults__) print(foo(),id(foo)) print(foo.__defaults__) 结果: [200] #函数结果 None 24057800 #函数id ([200], 1, 2) #函数默认值属性 [200, 200] #函数结果 None 24057800 #函数ID ([200, 200], 1, 2) #函数默认值属性
- 我们发现函数的对象ID,并没有变化,说明这个对象没有变
- 函数的默认值属性__defaults__是用元组保存的
- abc的默认值是可变类型 [ ],这里的变动只是默认值可变类型的该表,而不是整个元组的改变
例子:默认值非可变类型:常量
def foo(a,d = 1,e=2): d = 3 e = 4 print(a,d,e) print(foo.__defaults__) foo("123") print(foo.__defaults__) 结果: (1, 2) #函数的默认值 123 3 4 #函数的结果 (1, 2) #函数的默认值
函数中重新定义的默认值的数值,只是重新赋值,并不会改变函数的默认值,#函数的默认值是元组类型,也不会被改变的
简单来讲就是:函数属性__defaults__中使用元组保存所有位置参数默认值,它不会因为在函数体内使用了它而发生改变
例子:__kwdefaults__中使用字典保存所有keyword-only参数的默认值
def foo(a, b='abc', *, c=1, d=[]): b = 'xyz' c = 789 d.append(1) print(a, b, c, d) print(foo.__defaults__) foo('abc') print(foo.__kwdefaults__) 结果: ('abc',) # * 之前的默认值参数都是元组 abc xyz 789 [1] #函数结果 {'c': 1, 'd': [1]} # keyword-only形式的默认值参数
- 属性__defaults__中使用元组保存所有位置参数默认值
- 属性__kwdefaults__中使用字典保存所有keyword-only参数的默认值
默认的作用域有什么用?
- 使用可变类型作为默认值,就可能修改这个默认值
- 有时候这个特性是好的,有的时候这种特性是不好的,有副作用
- 如何做到按需改变呢?看下面的2种方法
方法一:可变数据类型:对引入的参数做影子拷贝,生成新的列表 【对原参数进行拷贝】
def foo(abc=[]): abc = abc[:] abc.append(200) print(abc) foo() print(1,foo.__defaults__) foo() print(2,foo.__defaults__) foo([100]) print(3,foo.__defaults__) foo([300]) print(4,foo.__defaults__) lis = [1,2] foo(lis) print(lis) 结果: [200] #结果 1 ([],) #参数默认的值属性 [200] #生成的结果 2 ([],) #参数的默认值属性 [100, 200] #参数传参后的列表结果 3 ([],) #参数的默认值属性 [300, 200] #参数传参后的列表结果 4 ([],) #参数的默认值属性 [1,2,200] #函数结果 [1,2] #传入的参数列表
- 通过上述函数:只是对函数的参数或者默认参数的副本,进行的拷贝,并不能改变元参数,
方法二:使用不可变类型的默认值 【对原参数结果改变】
def foo(abc=None): if abc == None: abc=[] abc.append(200) return abc lis = [1,2] b = foo(lis) print(b) print(foo.__defaults__) 结果: [1, 2, 200] #函数结果 (None,) #函数的缺省值
- 如果使用缺省值None就创建一个列表
- 如果传入一个列表,就修改这个列表
总结:
第一种方法
- 使用影子拷贝创建一个新的对象,永远不能改变传入的参数
第二种方法
- 通过值的判断就可以灵活的选择创建或者修改传入对象
- 这种方式灵活,应用广泛
- 很多函数的定义,都可以看到使用None这个不可变的值作为默认参数,可以说这是一种惯用法
最后
以上就是飘逸香氛为你收集整理的Python:函数默认值的作用域【__defaults__】【__kwdefaults__】的全部内容,希望文章能够帮你解决Python:函数默认值的作用域【__defaults__】【__kwdefaults__】所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复