鱼C论坛

 找回密码
 立即注册
查看: 1736|回复: 9

关于复制问题

[复制链接]
发表于 2021-7-16 16:16:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
def func(ls=[]):
    ls.append(1)
    return ls
a=func()
b=func()
print(a,b)
求大佬解释一下为什么答案是[1,1] [1,1]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-7-16 16:29:07 | 显示全部楼层
传入的参数为变量ls,指向的[]在定义函数之前创建,而不是每次执行前重新创建一个新列表对象
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-16 16:35:14 | 显示全部楼层
def func(ls):
    ls.append(2)
    print(ls)
    return ls
a=func([])
b=func([])
print(a,b)
在函数后面写参数的括号内定义列表,集合,字典都会这样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-16 16:36:10 | 显示全部楼层
灰晨 发表于 2021-7-16 16:29
传入的参数为变量ls,指向的[]在定义函数之前创建,而不是每次执行前重新创建一个新列表对象

那为何如果ls是字符就没事勒?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-16 16:46:05 | 显示全部楼层
a = func()时 调用一次 b = func()时又调用一次 且进行存储  print(a,b)时 就已经执行了俩次func()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-16 17:14:49 | 显示全部楼层
青出于蓝 发表于 2021-7-16 16:36
那为何如果ls是字符就没事勒?

像你的代码这样,只是 ls,就代表你这个参数没有默认值
没有默认值,你调用的时候就必须传参
a=func([])
b=func([])
这时 ls 这个变量指向的就是你传入的 []
你在函数里开头打印一下它的id
def func(ls):
    print(id(ls))
    ls.append(2)
    print(ls)
    return ls
a=func([])
b=func([])
print(a,b)
会发现,就算同样是 [] ,它们的储存地址也是不一样的,是不同的两个列表
而有默认值的参数,该默认值在定义函数前就创建了,类似于
a = []
def func(ls):
    print(id(ls))
    ls.append(2)
    print(ls)
    return ls
a=func(a)
b=func(a)
print(a,b)
就是说,你参数有默认值,而之后调用参数的时候没有进行传参,则 变量ls默认指向你的默认值的id,如
def func(ls=[]):
    print(id(ls))
    ls.append(2)
    print(ls)
    return ls
a=func()
b=func([6])
c=func()
print(a,b,c)
a没有进行传参,所以,ls默认指向[],在[]中添加2,成[2]
b进行了传参,则,ls指向传入的参数[6],在该列表中添加2,成[6,2]
注,此时实际有两个列表了,一个[2],另一个[6,2]
c同样没有进行传参,所以,ls依旧指向默认值的id,而此时该默认值为[2]
列表中的值虽然变了,不过列表还是默认的那个列表,在该列表中添加2,成[2,2]
即,此时python存储了两个列表,一个是默认的列表,一个是你自己定义的列表,
一个为[2,2], 一个为[6,2]
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-16 17:19:50 | 显示全部楼层
建议,默认值最好还是别设定成可变对象
代码很少还好说,代码一多,别人看起来,不,自己之后看都得疯
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-16 17:24:45 | 显示全部楼层
灰晨 发表于 2021-7-16 17:19
建议,默认值最好还是别设定成可变对象
代码很少还好说,代码一多,别人看起来,不,自己之后看都得疯


这个我懂,主要是按楼主的代码,他是在函数后那个传入参数括号内定义的变量,就出现了问题。但楼主将ls命名为了列表,如果ls是字符串,就不会有问题了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-16 17:35:48 | 显示全部楼层
本帖最后由 灰晨 于 2021-7-16 17:41 编辑
青出于蓝 发表于 2021-7-16 17:24
这个我懂,主要是按楼主的代码,他是在函数后那个传入参数括号内定义的变量,就出现了问题。但楼主将ls ...


因为字符串是不可变对象啊,比如说
def func(ls='a'):
    print(ls)
    print(id(ls))
    ls = ls + 'b'
    print(ls)
    print(id(ls))
    return ls
a=func()
b=func()
print(a,b)
你看,ls 指向默认值'a','a'的id是没有变,假如'a'的id是1234
那么,调用函数不传参,则,ls——>1234——>a
按楼主的代码,假如 [] 的id为789,
那么,调用函数不传参,则,ls——>789——>[]
但列表是可变对象啊,append(1)后[]就成了[1],可是列表还是那个列表,它的id没有变的
之后再调用函数不传参,就是,ls——>789——>[1]

ls = ls + 'b'
这里改变了 ls 的指向,ls 现在的指向是 'ab' , 'ab'的id 跟 'a' 的id 肯定不一样了
之后b=func(),此时再次调用还是不传参,ls 依旧是指向默认值,而默认值就是 id为 1234的 'a',而不是'ab'

评分

参与人数 1荣誉 +2 鱼币 +2 收起 理由
青出于蓝 + 2 + 2 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-17 07:00:43 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-14 01:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表