Python的类成员变量默认初始值的坑及解决
作者:zzx90 发布时间:2023-12-02 18:46:47
类成员变量默认初始值的坑
问题发现
一个循环内,缺省值初始化同名变量,其中的list成员不是空,会延续之前同名变量的值。
示例代码
# Define class
class Variant():
?? ?# use
?? ?def __init__(self, price = 500, description = 'default description', values = ['', '', '']):
?? ??? ?self.price = price
?? ??? ?self.description = description
?? ??? ?self.values = values
?? ?
?? ?def __str__(self):
?? ??? ?return 'price: {}, description: {}, values: {}'.format(self.price, self.description, self.values)
variant_list = []
# Create instance with same name iteratively
for i in range(3):
?? ?current_variant = Variant()
?? ?if i == 1:
?? ??? ?current_variant.values[2] = 'hello'
?? ?current_variant.price = i
?? ?current_variant.description = 'description of variant: {}'.format(i)
?? ?variant_list.append(current_variant)
?? ?
# Test results
for variant in variant_list:
?? ?print(str(variant))
结果
所有实例的values列表值相同
原因
可选参数默认值的设置在Python中只会被执行一次,也就是定义该函数的时候”如此使用缺省值初始化,list成员指向的是同一个list(地址),如果只是修改其中一个元素(而不是赋值新的list开辟新内存),那么所有instance的list成员都会被修改。
解决方法
直接在构造方法中置为空(self.values = ['', '', '']),之后各个修改值
Python默认值参数
简单粗暴上代码
def fun(a, b=[]):
? ? b += [a]
? ? print(b)
fun(1)
fun(2,[])
fun(3)
是不是看上去很简单,其实暗藏玄机,请大家看一下输出结果,是不是有点让你疑惑^^~
[1]
[2]
[1, 3]
此时你是否也和我有一样的疑惑,为什么 fun(3) 的输出结果是 [1, 3]?
哈哈,不卖关子了,这里是因为,因为函数被定义好后,只会生成一次,所以在函数生成的时候定义的变量 b 的默认值也只会被初始化一次。
因此,当执行fun(1)函数时,没有给 b 传参,所以使用的是 b 的默认值,此时 b 的默认值为[1]。
执行fun(2,[])时,给 b 传了一个[]值(恰好和默认值相同,其实是不同的数据),因此便使用的是传入数据,执行结果便是[2]。
然后在执行fun(3),此刻又没有给 b 传参,所以依旧使用的是 b 的默认值, 而 b 的默认值只会随着函数的生成被生成一次 ( fun(1) 生成过了 ),所以现在的默认值是fun(1)的执行结果[1],因此当fun(3)再次调用时,输出结果便会是[1, 3]。
如果不行出现当前这种情况,而是在函数每次被调用的时候都初始化一次变量
可以用下面这种写法
def function(a, b=None):
? ? b = b if b else [] ?# 明确每次重新定义b
? ? b += [a]
? ? print(b)
function(1)
function(2, [])
function(3)
输出结果:
[1]
[2]
[3]
来源:https://blog.51cto.com/u_8878683/2348528
猜你喜欢
- 创建一个名为templatetags的python module。新建一个名为verbose_name.py的文件。from django
- 概要:Oracle关系数据库系统以其卓越的性能获得了广泛的应用,而保证数据库的安全性是数据库管理工作的重要内容。本文是笔者在总结Oracle
- 例如<div id="info"><span><span class='pl
- CNN(Convolutional Neural Networks) 卷积神经网络简单讲就是把一个图片的数据传递给CNN,原涂层是由RGB组
- 如何实现刷新当前页面呢?借助js你将无所不能。1,reload 方法,该方法强迫浏览器刷新当前页面。语法:location.reload([
- 如下所示:def test1(): try: print('to do stuff')  
- 输出电脑上所有的串口名:import serialimport serial.tools.list_portsfrom easygui im
- 那就废话不多说,直接上代码吧!new_array = np.zeros((107,4))# 共107行 每行4列 初值为0>>&
- 我就废话不多说了,直接上代码吧!conv1=nn.Conv2d(1,2,kernel_size=3,padding=1)conv2=nn.C
- 本文实例为大家分享了python批量梯度下降算法的具体代码,供大家参考,具体内容如下问题:将拥有两个自变量的二阶函数绘制到空间坐标系中,并通
- 本文实例为大家分享了Python实现图书馆座位自动预约的具体代码,供大家参考,具体内容如下配置通过公网主机定时运行脚本,并发送邮件到自己的q
- 在一些微服务或web服务中我们难免需要日志功能,用来记录一些用户的登录记录,操作记录,以及一些程序的崩溃定位,执行访问定位等等;Python
- Server对象主要是给编程人员提供一些方便的对象和属性。(1)ScriptTimeout属性:<%Server.ScriptTime
- 最近用python写了一个远程监控的程序,主要功能有:1.用邮件控制所以功能2.可以对屏幕截图,屏幕截图发送到邮箱3.可以用摄像头获取图片,
- 需求对于部署在阿里云上的重要系统一般是不让其他人访问的,所以会在负载均衡(SLB)上加上访问控制列表。而使用ASDL拨号上网的宽带来说一般公
- 钉钉开放平台传送门:https://open.dingtalk.com我司使用钉钉作为内部通讯工具,基本上大家在电脑和手机上都开着,消息可以
- 本文实例为大家分享了python3设计签名小程序的具体代码,供大家参考,具体内容如下首先,上一下要做的效果图:先是这样一个丑陋的界面(我尽力
- MySQL Proxy(MySQL代理)是一个通过MySQL网络协议,提供MySQL服务器与客户端之间连接的应用工具,在基本配置条件下,My
- Python 多线程多线程类似于同时执行多个不同程序,多线程运行有如下优点:使用线程可以把占据长时间的程序中的任务放到后台去处理。用户界面可
- 笔者remove TensorFlow总共四次。 reinstall anaconda 三次。安装技巧可以根据这个博主的文章进行安装。htt