类属性

类属性:

1、基本特点:

通常情况下通过类方法来修改类属性,这样避免很多麻烦。当然,类名和对象也可以调用修改,区别是类名修改的是唯一备份,所有的对象都要跟着改变;对象也可以在类外调用类属性进行修改,会产生“屏蔽”,也就会给当前对象创建新的实例属性,进而通过简单的对象访问,访问不到类属型,只会返回和修改实例属性,相当于类属型暂时对此对象“屏蔽”了。

class A(object):
    B = 4  # 类属性B
    
a = A()
b = A()   
a.B = 6	# 通过对象a修改类属性,其他对象的类属性因被屏蔽不会发生修改
print(a.B)
print(b.B)	  # 运行结果 6 4
print(a.__class__.B)	# 结果是6
# a的类属性并没有被修改只是,被新创建的a实例属性屏蔽了
A.B = 6   # 通过类名修改类属性,直接修改了唯一备份,所以都会被修改
print(a.B)
print(b.B)  # 运行结果 6 6

2、单例模式

在单例模式下的类属性,所有的对象被赋予了同一个内存地址。此时类属性被cls使用,而cls就等同于类名的调用,所以效果同上。联想到类方法传参也是cls,所以也是相同效果。

class A(object):
    object_catch = None # 定义类属性object_catch用于捕获对象
    def __new__(cls, num):
        if cls.object_catch is None:
            cls.object_catch = super().__new__(cls)
        return cls.object_catch

    def __init__(self, num):
        self.num = num
        # print("%s" % num)

a = A(1)
print(a.num)
A.object_catch = None  # 通过类名给类属性赋值
b = A(2)
print(a.num, b.num)  # 执行结果 1 2说明a,b是两个独立对象

a = A(1)
print(a.num)
a.object_catch = None  # 通过类对象给类属性赋值,发生屏蔽
b = A(2)
print(a.num, b.num)  # 执行结果 2 2说明a,b是不是独立对象

3、self使用类属性

单例模式下,如果我们的类属性通过self使用(如实例方法)的话,首先这是很不规范的,正是由于这种不规范操作导致了特殊情况

class A(object):
    object_catch = None
    def __new__(cls, mem):
        if cls.object_catch is None:
            cls.object_catch = super().__new__(cls)
        return cls.object_catch
    is_First = True
    def __init__(self, mem):   
        # print(A.is_First)     # 测试A.is_First的值 
        # print(self.is_First)    # 测试self.is_First的值
        if self.is_First is True:
                   self.name = mem
                   print("%s"%mem)
                   self.is_First = False

a = A(23)
a.is_First = True   #  如果A.is_First  = True 则b不会被实例化 执行结果:23
b = A(1)   #  执行结果 23 1

此时由于在魔法方法中使用self调用了类属性is_First,不规范的使用导致只能通过对象调用is_First才能使得被修改的is_First发挥作用。

小结:

类属性的可以被类方法,实例方法,类名,对象调用。但是实例方法调用属于不规范的情况,需要特别注意,对象调用会出现屏蔽现象。 由此,类方法的意义也就显现出来了,他能够没有异议的对共有类属性修改而不出现屏蔽等现象。

从地址层面理解类属性:类A实例化对象a,b,对于类属性,实例属性,类方法,实例方法而言,A跟对象a,b的存储地址是相同的。对于类属性,我们使用类名或者类方法修改值,存储他们的存储地址是不会发生改变的(总是类中类属性的地址)。如果通过对象名修改类属性,则会发生“屏蔽”,导致对象的类属性地址发生改变,也就无法通过类改变类属性的值改变对象类属性的值,因为他们的地址已经不相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值