马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
类变量会共享变量吗?小甲鱼在讲类的时候说不会,视频地址:发不了URL,视频是 【Python教程】《零基础入门学习Python》最新版(2022年09月29日更新)P59 6:02的地方
但是在这个类A中,我用self.aList.extend(value)每个对象都好像共享了这个类变量aList
而当我用self.aList = value时就不会有这种情况了,这是怎么回事,各位大佬能解释一下吗
class A:
aList = []
def __init__(self, value=None):
if value is None:
return
self.aList.extend(value) # 这是用self.aList.extend(value)
print(self.aList)
aas = [A() for _ in range(10)]
d = A(aas)
print(d.aList)
print(d.aList[0].aList)
# 结果如下
[<__main__.A object at 0x000001A0DB5C5D20>, <__main__.A object at 0x000001A0DB5C5FC0>, <__main__.A object at 0x000001A0DB5C5FF0>, <__main__.A object at 0x000001A0DB5C5750>, <__main__.A object at 0x000001A0DB5C5E70>, <__main__.A object at 0x000001A0DB5C61A0>, <__main__.A object at 0x000001A0DB5C61D0>, <__main__.A object at 0x000001A0DB5C6200>, <__main__.A object at 0x000001A0DB5C6230>, <__main__.A object at 0x000001A0DB5C6170>]
[<__main__.A object at 0x000001A0DB5C5D20>, <__main__.A object at 0x000001A0DB5C5FC0>, <__main__.A object at 0x000001A0DB5C5FF0>, <__main__.A object at 0x000001A0DB5C5750>, <__main__.A object at 0x000001A0DB5C5E70>, <__main__.A object at 0x000001A0DB5C61A0>, <__main__.A object at 0x000001A0DB5C61D0>, <__main__.A object at 0x000001A0DB5C6200>, <__main__.A object at 0x000001A0DB5C6230>, <__main__.A object at 0x000001A0DB5C6170>]
[<__main__.A object at 0x000001A0DB5C5D20>, <__main__.A object at 0x000001A0DB5C5FC0>, <__main__.A object at 0x000001A0DB5C5FF0>, <__main__.A object at 0x000001A0DB5C5750>, <__main__.A object at 0x000001A0DB5C5E70>, <__main__.A object at 0x000001A0DB5C61A0>, <__main__.A object at 0x000001A0DB5C61D0>, <__main__.A object at 0x000001A0DB5C6200>, <__main__.A object at 0x000001A0DB5C6230>, <__main__.A object at 0x000001A0DB5C6170>]
class A:
aList = []
def __init__(self, value=None):
if value is None:
return
self.aList = value #这是用self.aList = value
print(self.aList)
aas = [A() for _ in range(10)]
d = A(aas)
print(d.aList)
print(d.aList[0].aList)
#结果如下
[<__main__.A object at 0x000001E6C0385D20>, <__main__.A object at 0x000001E6C0385FC0>, <__main__.A object at 0x000001E6C0385FF0>, <__main__.A object at 0x000001E6C0385750>, <__main__.A object at 0x000001E6C0385E70>, <__main__.A object at 0x000001E6C03861A0>, <__main__.A object at 0x000001E6C03861D0>, <__main__.A object at 0x000001E6C0386200>, <__main__.A object at 0x000001E6C0386230>, <__main__.A object at 0x000001E6C0386170>]
[<__main__.A object at 0x000001E6C0385D20>, <__main__.A object at 0x000001E6C0385FC0>, <__main__.A object at 0x000001E6C0385FF0>, <__main__.A object at 0x000001E6C0385750>, <__main__.A object at 0x000001E6C0385E70>, <__main__.A object at 0x000001E6C03861A0>, <__main__.A object at 0x000001E6C03861D0>, <__main__.A object at 0x000001E6C0386200>, <__main__.A object at 0x000001E6C0386230>, <__main__.A object at 0x000001E6C0386170>]
[]
[b]
类变量属于这一类,所有此类的实例都会共享这个变量,即类变量
而类变量的赋值方式是在类中且类的方法外的空间,进行 变量名 = 属性值 这样赋值,被称为类变量
而在类方法中,进行 变量名 = 属性值 这样的赋值属于局部变量,出了这个方法就无法找到此变量了
最后 self.变量名 = 属性值 这种赋值方式的变量名被称为 实例变量,即每个实例对象都会有的属性,但不共享
而这里共享是因为,aList 这个变量在 A 类中是类变量,当你第一次创造实例在初始化方法中又进行了 self.aList 列表的合并
此时 self.aList 列表,会先在实例对象中寻找 aList 属性,发现实例对象没有 aList 属性,就会去类变量中找 aList,所以此时找到了 aList 这个类属性
你对这个类属性进行列表合并,不是创建新的列表,而是在原列表上进行合并
自然会共享所有整个类对象中的 aList 变,但第二段代码,你是对这个实例对象进行重新赋值,那么此时就是进行实例属性的赋值,即 self.aList 就会 "覆盖" 类变量的 aList
当你再进行访问时,你访问的是实例的 aList ,而不是类本身定义的类变量 aList,看下下面这两段代码,可能更有助于你理解:
class A:
aList = []
def __init__(self, value=None):
if value is None:
return
self.aList.extend(value) # 这是用self.aList.extend(value)
print(id(self.aList))
print(id(A.aList))
aas = [A() for _ in range(10)]
d = A(aas)
print(id(d.aList))
print(id(d.aList[0].aList))
# 输出结果一定会是四个相同的地址,因为都是类变量 aList
class A:
aList = []
def __init__(self, value=None):
if value is None:
return
self.aList = value
print(id(self.aList)) # # 第二个 print
print(id(A.aList)) # 第一个 print
aas = [A() for _ in range(10)]
d = A(aas)
print(id(d.aList)) # 第三个 print
print(id(d.aList[0].aList)) # 第四个 print
# 输出结果,一定是第一个 print 和 第四个 print 地址值相同,其余两个相同,因为 前者是类属性,后者是实例属性
[/b]
|