Python类的组合时产生的属性同步改变问题

问题引入:

class A:
    x = 1
class B:
    t = A()

b1 = B()
b2 = B()
b1.t.x = 2
print(b2.t.x)

>>>   2

为什么操作对象b1 会改变另一个对象 b2 的属性值?对象之间的属性应该相互独立?难道类的对象属性和列表一样是一种可变属性,操作对象属性会改变类属性,从而改变了另一个该类实例中的属性?

print(A.x)>>> 1

发现类属性并没有被改变

查阅多方资料后,发现这种情况和实例的创建规则有关

class A:
    x=1

a=A()
print(id(a.x))
print(id(A.x))
A.x=2
print(id(a.x))
print(id(A.x))
a.x=4
print(id(a.x))
print(id(A.x))

>>>140722909176464         #显然开始实例属性会指向类属性,他们是同一个地址
>>>140722909176464

>>>140722909176496         #改变了类属性,实例属性会跟着转变指向新的地址
>>>140722909176496

>>>140722909176560         #但是改变了实例的属性,对象创建了自己的x,看到地址改变了>>>140722909176496         #而类属性并不受影响

但是

def out():    print("我被创建了")

class A:  x = 1    def __init__(self):        out()

class B:    t=A()
>>> “我被创建了”

#对象作为属性时,在定义时就被创建处一个A对象,后续不会再次创建#这就是它与普通属性的本质区别了。
s1 = B()    s1.t.x = 2          #改变了对象的属性,理应创建自己的tprint(id(B.t))print(id(s1.t))
>>>1730846532384      #但是和上面的普通属性不同,这里s1没有创建一个新的A类实例,而是用了同一个对象t,所以后来再创建s2也是沿用t,自然看到x被改变了>>>1730846532384      #打印出A类的x,发现并没有被改变,这也证明了它们并没有改变A的类属性。而是用的都是同一个A的实例t

原文地址:https://www.cnblogs.com/Poceer/p/10927106.html

时间: 2024-07-31 18:31:39

Python类的组合时产生的属性同步改变问题的相关文章

python类内init外声明的属性与init内声明的对象属性的访问和操作区别

python类内init外声明的属性与init内声明的对象属性的访问和操作区别(面试题) 1.在ipython中输入以下代码,其输出会是什么? In [1]: class ClassOut: ...: out_mem = 'out_mem' ...: print out_mem ...: def __init__(self): ...: inner_mem = 'inner_mem' ...: self.inner_mem = 'self.inner_mem' ...: self._inner_

python类的组合

类的组合,即在类实例化时,将另一个类的实例作为参数传入,这样可以将两个实例关联起来. 当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好. 例如,描述一个机器人类,这个大类是由很多互不相关的小类组成,如机械胳膊类.腿类.电池类等. 当类之间有很多相同的属性,提取这些统统的属性做成基类,用继承比较好. class course: def __init__(self,name,price,period,teacher): self.name=name self.price=pri

揭秘DOM中data和nodeValue属性同步改变那些事

问题引发:最近在整理DOM系列的一些知识点,发现在DOM的某些接口API中,存在一些我想不通的现象.就随便举个例子吧:DOM文档模型中的文本节点,可以通过nodeValue或data属性访问文本节点的文本内容,而且在更新data的时候nodeValue也即时更新,反之亦然.不光是data或nodeVaulue有这种相互影响的关系,其他类型节点也有比如该改变document.title也会随之改变网页标题.当时想弄明白这在JS引擎中是怎么实现的,于是乎进行了以下分析:通过文本节点的原型链继承关系

Python类的定义、方法和属性使用

类用来描述具有相同的属性和方法的对象的集合.对于在类中定义的函数,称为方法.类变量不直接叫做类变量,称为属性. 1.类的定义 例子: class User(): pass 说明: (1)定义了一个类名为User的类(2)类名一般约定用大写字母开头,函数则用小写字母开头,以做区分(3)用pass表示为空类,暂时还没准备好类的内容 2.类的方法 例子: class User(): def say(self) -> None: print('hello') 调用: a = User() a.say()

C++类的组合、前向引用声明

3.5类的组合 Part1.应用背景 对于复杂的问题,往往可以逐步划分为一系列稍微简单的子问题. 解决复杂问题的有效方法是将其层层分解为简单的问题组合,首先解决简单问题复杂问题也就迎刃而解了. 在面向对象的程序设计中,可以对复杂对象进行分解.抽象,把一个复杂对象分解为简单对象的组合,由比较容易理解和实现的部件对象装配而成. Part2.定义及代码 ①定义:类的组合描述的就是一个雷内嵌其他类的对象作为成员的情况,他们之间的关系是一种包含与被包含的关系. ②作用机制:当创建类的对象时,如果这个类具有

Python学习之旅—面向对象进阶知识:类的命名空间,类的组合与继承

前言 上篇博客笔者带领大家初步梳理了Python面向对象的基础知识,本篇博客将专注于解决三个知识点:类的命名空间,类的组合以及面向对象的三大特性之一继承,一起跟随笔者老看看今天的内容吧. 1.类的命名空间 在上一篇博客中,我们提到过对象可以动态添加属性,一起来回忆下昨天的知识点,看如下的代码: class A: pass a = A() a.name = 'alex' print(a.name) 这里我们手动为a对象添加了一个属性name,然后直接打印可以得到a对象的名称.通过这个例子,我们可以

Python类属性访问的魔法方法

Python类属性访问的魔法方法: 1. __getattr__(self, name)- 定义当用户试图获取一个不存在的属性时的行为 2. __getattribute__(self, name)- 定义当该类的属性被访问时的行为 注意:当__getattr__与__getattribute__同时重写时,访问属性时,优先调用__getattribute__,只有当被访问的属性不存在时才触发__getattr__ 3. __setattr__(self, name, value)- 定义当一个

python 类组合

在使用一款云产品的python sdk过程中,发现了python类之间调用的另一种少见方法:类组合,那么类组合是用来干吗的呢? 我们知道,在python中,类之间的相互调用,我们习惯性的采用继承的方法,但是 除了继承方法,我们还可以采用类组合的方式来调用另一个类 官方的说法:让不同的类混合并加入到其他类中,来增强功能和代码重用性.你可以在一个大点的类中创建你自己的类的实例,实现一些其他属性和方法来增强原来的类对象. 举个例子: >>> class Name(object):       

Python 类属性与实例属性的关联

类属性是属于一个类的变量,就像是C++中类的静态成员变量,你只需将该属性定义在所有方法的作用域外,即为类属性,但一般是紧跟在类名后面,类属性为所有实例所共有,你可以通过 类名.属性 来调用类属性 >>> class A:       count = 0; #这就是类属性       def __init__(self):           A.count += 1  #每次调用该方法 count 自增 1       def output(self):           print(