Python类对象属性变更困惑:调用方法后原对象属性为何被修改
关于Python类实例方法修改属性的疑问
代码示例
class Cats: def __init__(self,name): self.name=name #print(self.name,name,"hello") def change_name(self,new_name): self.name=new_name return 0 #print(new_name) cat1=Cats("lion") print(cat1) print(cat1.name) cat2=cat1.change_name("tiger") print(cat1.name) print(cat1) print(cat2)
输出结果及疑问
<__main__.Cats object at 0x7f84272d7640>:我以为这是错误,因为我想打印对象cat1lion:这部分没问题,打印对象的属性,初始化时name设为lion,所以输出liontiger:这是我不理解的地方:为什么输出是tiger而非lion?是什么导致了这个变更?我执行cat2=cat1.change_name("tiger")时,应该只是把0赋值给cat2,但为什么cat1的属性值被修改了?我原本预期cat1.name的值保持不变(应该仍然是lion而非tiger)<__main__.Cats object at 0x7f84272d7640>:我以为这是错误,因为我想打印类0:这部分没问题,change_name方法返回0并赋值给了cat2
问题解答
1. 打印对象显示内存地址不是错误
Python直接打印对象时,默认会输出对象的类名和内存地址,这是正常行为。如果想让打印结果更直观,只需在类中定义__str__方法:
def __str__(self): return f"Cats(name={self.name})"
之后打印cat1就会输出Cats(name=lion)这类清晰的内容。
2. cat1.name被修改的原因
你调用cat1.change_name("tiger")时,方法内部的self指代的就是调用该方法的实例cat1,self.name = new_name直接修改了cat1的属性值。
cat2 = cat1.change_name("tiger")的执行逻辑是:先运行change_name方法修改cat1的name为tiger,再把方法返回的0赋值给cat2。所以cat2得到的是返回值,但cat1的属性已经被方法内部改动了。
如果想保留原实例的属性不变,可以让方法返回新的实例而非修改原实例:
def change_name(self, new_name): return Cats(new_name)
这样cat2 = cat1.change_name("tiger")会生成一个新的name为tiger的Cats实例,cat1的name仍为lion。
内容的提问来源于stack exchange,提问作者Vikrant KALKAL
相关产品推荐
相关产品推荐

