kking1 发表于 2023-3-3 12:46:20

类变量赋值相关问题

class aa:
    def __init__(self):
      self.s1 = None
      self.s2 = None

    def asa(self,bb):
      self.s1 = bb
      p = self.s1
      self.s2 = p
      return p
      
      #return self.s2
    def sadsa(self):
      self.s1.id = 3
class bb:
    def __init__(self):
      self.id = 0

    def setId(self,id):
      self.id = id

c = bb()
c.setId(2)
#print(c.id)
d = aa()
d.asa(c)
d.sadsa()
print(d.s2.id)
#print(d.asa(c).id)
#print(c.id)

求问,为啥打印出来得值是3,明明给s2赋值时候是2,之后只是s1变了,为啥s2的值跟着一起变了,怎么样使得s2不跟着一起变呢?即打印出来得值为2




#def reyu():
#    a = 1
#    b =2
#    return a,b
#
#c = reyu()
#print(c)

isdkz 发表于 2023-3-3 12:53:25

这是因为在 asa 方法中,self.s1 和 self.s2 都被赋值为指向同一个对象 bb 的引用。

所以当你在 sadsa 方法中更改了 self.s1.id 的值时,

由于 self.s1 和 self.s2 指向的是同一个对象,所以打印出来的值也会随之改变。

如果你想让打印出来的值为2,可以在给 self.s2 赋值时创建一个新的对象并将其属性设置为与原对象相同。

例如,在 asa 方法中,可以将代码更改为:

def asa(self, bb):
    self.s1 = bb
    p = bb.__class__()
    p.__dict__ = bb.__dict__.copy()
    self.s2 = p
    return p

这样,在调用 d.asa(c) 后,d.s2.id 的值就会保持不变。

kking1 发表于 2023-3-3 13:44:41

isdkz 发表于 2023-3-3 12:53
这是因为在 asa 方法中,self.s1 和 self.s2 都被赋值为指向同一个对象 bb 的引用。

所以当你在 sadsa...

有没有类似赋值的功能而不是对相关对象的引用呢?赋值之后就静态不动了

isdkz 发表于 2023-3-3 13:51:35

kking1 发表于 2023-3-3 13:44
有没有类似赋值的功能而不是对相关对象的引用呢?赋值之后就静态不动了

在 Python 中,赋值过程中不明确区分拷贝和引用。

一般对静态变量的传递为拷贝,对动态变量的传递为引用。

你可以使用深拷贝来实现你想要的效果。

import copy                                                    # 引入 copy 模块
class aa:
    def __init__(self):
      self.s1 = None
      self.s2 = None

    def asa(self,bb):
      self.s1 = bb
      self.s2 = copy.deepcopy(bb)                           # 用深拷贝
      return self.s2
      
      #return self.s2
    def sadsa(self):
      self.s1.id = 3
class bb:
    def __init__(self):
      self.id = 0

    def setId(self,id):
      self.id = id

c = bb()
c.setId(2)
#print(c.id)
d = aa()
d.asa(c)
d.sadsa()
print(d.s2.id)
#print(d.asa(c).id)
#print(c.id)

kking1 发表于 2023-3-3 15:27:09

isdkz 发表于 2023-3-3 13:51
在 Python 中,赋值过程中不明确区分拷贝和引用。

一般对静态变量的传递为拷贝,对动态变量的传递为 ...

这个深拷贝和你楼上那个方法有什么区别?

歌者文明清理员 发表于 2023-3-3 17:25:38

本帖最后由 歌者文明清理员 于 2023-3-3 17:27 编辑

kking1 发表于 2023-3-3 15:27
这个深拷贝和你楼上那个方法有什么区别?

对普通元素来说没有区别,但是对可变对象来说不是
比如
lista = [, , 6]
listb = lista.copy()
listb = 5
print(lista)
# [, , 6]
因为listb和lista虽然不是一个东西,但是他们的元素一样,是同一个东西
用deppcopy相当于会把and 也拷贝一次
页: [1]
查看完整版本: 类变量赋值相关问题