ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

实例变量与类变量不得不说的二三事

2021-05-12 20:33:23  阅读:216  来源: 互联网

标签:__ 变量 Chinese self 二三 实例 age name


1. 类变量作用及解析

类变量:实例共用的属性。 比方说country 这个属性如果设置为实例属性,创建5个对象的时候,country 就需要初始化5次,但这个属性对于各个实例是相同的,每次都需要创建会造成资源浪费。类变量只会在创建类的时候生成一次,对于不同对象来说无区别的对象我们可以设置为类变量。
class Chinese:
    country = 'China'
    def __init__(self, name, age,country):
        self.name = name
        self.age = age
        self.country = country  

2. 类变量、实例变量查找优先级

优先查找实例变量,找不到再去查找类变量。就是说类变量和实例变量名相同的情况下,返回的是实例变量的值,代码如下:
class Chinese:
    country = 'China'
    age = 72
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def talk(self):
        print(self, 'is talking Chinese')
if __name__ == '__main__':
    DY = Chinese("DY", "18")
    print(DY.age)
    
执行结果:
18  # 18为实例DY的属性值

3. 实例增删改查类的变量、方法

实例是可以直接操作类的变量或方法的,可进行查询、更改、新增、删除的,如果是使用这些方法时,仅推荐操作实例属性,其他属性因为存储在类的命名空间内,操作的话会影响其他实例,Python真的是很不严谨;但其实实例的属性、方法也是不推荐操作如更改、删除的,这就引入了私有变量或方法。

class Chinese:
    country = 'China'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def talk(self):
        print(self, 'is talking Chinese')

    @staticmethod
    def nationality():
        print("国籍归属于{}".format(Chinese.country))


if __name__ == '__main__':
    DY = Chinese("DY", 18)
    print(DY.age)  # 查询实例变量值
    DY.age = 19   # 更改实例变量的值,思考更改类变量的值?
    print(DY.age)
    DY.sex = "女"  # 对象新增实例变量
    print(DY.sex)
    del DY.talk  # 删除实例属性,慎用删除
    print(DY.talk)

4. 实例可以更改类变量值吗?

实例对类变量赋值(更改类变量)为什么未改变类变量值?对象给类变量赋值实际是给实例增加一种新的属性,是在对象内存空间中新增了一个变量,而使用变量的时候又是优先查找实例变量,所以打印对象的类变量时,实际是查的对象的实例属性,从根本上并未影响到类变量,也就不会影响到其他对象的类变量值。 简而言之,你觉得是在更改类变量的值,实际是给实例新增了一个实例属性。
class Chinese:

    country = 'China'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def talk(self):
        print(self, 'is talking Chinese')

if __name__ == '__main__':
    DY1 = Chinese("DY", "18")
    DY2 = Chinese("DY", "19")
    DY1.country = "zhongguo"
    print(DY1.country)
    print(DY2.country)

执行结果:
zhongguo  # 实际相当于给实例DY1新增了个实例属性
China     # 实例DY2并不受影响

5. 慎用del 删除类变量、类方法、实例方法

在Python中,类变量、类方法、实例方法存储在类的内存空间中,对象删除这些属性、方法是从类内存空间中真正删除,至于为什么可以这么做,这也是Python不严谨的地方,建议大家最好不要这么做。
class Chinese:

    country = 'China'
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def talk(self):
        print(self, 'is talking Chinese')

if __name__ == '__main__':
    DY1 = Chinese("DY", "18")
    del DY1.country
    print(Chinese.country)
    
执行结果:
Traceback (most recent call last): 
  File "question.py", line 665, in <module> 
    del DY1.country 
AttributeError: country

6. 类属性慎用可变数据结构

class Chinese:
    country = 'China'
    populations = []

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def talk(self):
        print(self, 'is talking Chinese')

    @staticmethod
    def nationality():
        print("国籍归属于{}".format(Chinese.country))

    def add_people(self):
        Chinese.populations.append(self.name)


if __name__ == '__main__':
    DY1 = Chinese("DY", 18)
    DY2 = Chinese("DY1", 18)
    DY1.add_people()
    print(DY1.populations)
    DY2.add_people()
    print(DY2.populations)
   
执行结果:
['DY'] 
['DY', 'DY1']
由执行结果可以看出,两个实例同时操作类变量时是会相互影响的, 对象DY1操作populations属性也会影响到DY2的populations ,如果是在程序中是会出bug的,而且问题不好查找,就好比说对象A与对象B同时在做任务,并且共享任务列表,对象A完成后发通知说任务已完成,导致对象B实际未做完也发通知报告已完成。 划重点:可变数据结果一般不能用作类变量的值。如果变量的值为可变数据,需要写在__init__里面,写成self. populations = [],这样在初始化对象的时候,每个对象的populations的值都会初始化为一个空列表,对象间属性独立。  

标签:__,变量,Chinese,self,二三,实例,age,name
来源: https://www.cnblogs.com/dy99/p/14761513.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有