类属性和__init__的实例属性有何区别?进来了解一下吧

真的是随笔写的一篇,以防日后记忆模糊,特此记录。大佬勿喷

疑问:类属性和实例属性有何区别?

 

正题,代码如下

age为People类的属性(称为类属性)

name是在__init__方法下,在创建实例对象的时候会自动调用,是动态创建的属性(称为实例属性)

class People:
    age = 18

    def __init__(self):
        self.name = "小米"

xm = People()

print(People.age)   # 类调用类属性
print(xm.age)       # 实例对象调用类属性
print(xm.name)      # 实例对象调用实例属性

代码似乎没什么问题,当然输出也没问题

18
小米
18

这个时候插入这样一段代码

print(People.name)  # 类调用实例属性

奇怪的事情发生了,程序运行之后抛出以下异常

Traceback (most recent call last):
  File "/Users/jinfukang/Desktop/metisPushRateMonitor/demo.py", line 14, in <module>
    print(People.name)  # 类调用实例属性
AttributeError: type object 'People' has no attribute 'name'

那么从异常信息看出说:People类没有name属性??

其实这是因为类在实例化之后只能通过实例对象去调用实例属性

 

继续,代码如下

class People:
    age = 18

    def __init__(self):
        self.name = "小米"

xm = People()

People.age += 1        # 通过类调用类属性,使其属性值+1

print(xm.age)        # 实例化对象调用类属性
print(People.age)      # 类调用类属性

19
19

貌似没什么问题,继续,代码修改为如下

class People:
    age = 18

    def __init__(self):
        self.name = "小米"

xm = People()

xm.age += 1             # 通过实例对象调用类属性,使其值+1
print(People.age)       # 类调用类属性
print(xm.age)           # 实例对象调用类属性

18
19

what???

使用类调用类属性+1,People.age和xm.age的值相等

使用实例对象调用类属性+1,People.age和xm.age的值竟然发生了变化。。。

按照咱们的期望,这2个值应该相等才对,可是为什么不一样了呢,接下来一起剖析一下

class People:
    age = 18

    def __init__(self):
        self.name = "小米"

xm = People()

print("类调用类属性", id(People.age))
xm.age += 1                                                     # 查看id,通过实例对象调用类属性,使其值+1
print("类调用类属性", id(People.age))                             # 类调用类属性的,查看id
print("实例对象调用类属性", id(xm.age))                            # 实例对象调用类属性,查看id

类调用类属性      4486466752
类调用类属性      4486466752
实例对象调用类属性 4486466784

由输出可以看出:

通过实例对象调用类属性+1前后,类调用类属性的身份证没有变化;实例对象调用的类属性身份证变了

这是不是可以说明 People.age和xm.age指向的不是同一个对象,为什么会这样呢,继续分析

这里就需要引入作用域的概念了: __init__的作用域只在自己的方法内,对于类属性它有访问的权限,但没有修改的权限

使用实例对象调用类属性使其值+1的时候,实例对象会在自己的作用域下创建一个age属性,将类属性的值拿过来并+1

对象调用age属性的时候,会先检查自己的作用域有没有age,如果有直接调用,所以类的age属性和对象的age属性的id发生变化

 

 

 

 

随笔记,有错误/遗漏的地方还请大佬指出,小弟感激不尽

 

posted @ 2020-12-13 22:33  Fighting_to_light  阅读(269)  评论(0)    收藏  举报