📚前言
✅本次主要介绍的是类的进阶知识点,其中包括类的命名空间等等知识点,进一步了解并熟练使用类,了解类中对静态属性和对动态属性的修改有什么区别呢?
文章目录
📚前言
📚结语
🌄一、初识命名空间
要了解类的命名空间首先我们先创建一个类,如下
class Course: language = 'Chinese' #静态属性 def __init__(self, teacher, course_name, period, price): self.teacher = teacher self.name = course_name self.period = period self.price = price def func(self): #动态属性 pass
现在我们就创建了一个Course类,类里面可以定义两种属性:静态属性和动态属性。
🌄二、__dict__方法
类的静态函数,类函数,普通函数,全局变量以及内置属性都放在类__dict__中,对象的__dict__中存储了self.xx的东西
print(Course.__dict__) 输出结果: {'__module__': '__main__', 'language': 'Chinese', '__init__': <function Course.__init__ at 0x000002076A703EE0>, 'func': <function Course.func at 0x000002076D26F5E0>, '__dict__': <attribute '__dict__' of 'Course' objects>, '__weakref__': <attribute '__weakref__' of 'Course' objects>, '__doc__': None}
我们可以发现__dict__方法中包含Course中的所有属性,并且返回的是一个字典
但是不可以通过直接修改字典的方法来改变类的静态属性
Course.__dict__['language'] = 'Chinese' print(Course.language) 输出结果: Course.__dict__['language'] = 'Chinese' TypeError: 'mappingproxy' object does not support item assignment 翻译:TypeError:“mappingproxy”对象不支持项目分配
但是可以用如下方法对类中的静态属性进行修改
Course.language = 'English' print(Course.language) 输出结果: English
🌄三、为实例化对象和类创建的内存空间
我们首先实例化两个对象
python = Course('Lisa','python','6 months',20000) linux = Course('Bob','linux','6 months',20000)
其中实例化对象python和linux和Course类的内存空间的关系如下图:
每当一个对象调用自己的属性时,会优先从自己的内存空间中寻找,如果找不到的话就到自己类的内存空间中寻找,如果还找不到的话就会报错。
🌄四、静态属性修改知识点
观察以下两个代码结果的区别和为什么会产生这种区别
代码一
class Course: language = 'Chinese' def __init__(self, teacher, course_name, period, price): self.teacher = teacher self.name = course_name self.period = period self.price = price python = Course('Lisa','python','6 months',20000) linux = Course('Bob','linux','6 months',20000) Course.language = 'English' print('Course:',Course.language) print('python: ',python.language) print('linux: ',linux.language) 输出结果: Course: English python: English linux: English
代码二
class Course: language = 'Chinese' def __init__(self, teacher, course_name, period, price): self.teacher = teacher self.name = course_name self.period = period self.price = price python = Course('Lisa','python','6 months',20000) linux = Course('Bob','linux','6 months',20000) python.language = 'English' print('Course:',Course.language) print('python: ',python.language) print('linux: ',linux.language) 输出结果: Course: Chinese python: English linux: Chinese
绘图解释代码二出现的原因,没有改变类中的language,而是在Python命名空间中创建了一个language = 'Chinese'
小结
所以从以上我们可以得出一个结论
- 类中的静态变量 可以被对象和类调用
- 对于不可变数据类型来说,类变量最好用类名操作
🌌1、del的使用
因为代码二出现的原因,没有改变类中的language,而是在Python命名空间中创建了一个language = 'Chinese',所以之后python这个实例化的对象就再也拿不到类中的language静态属性了。
但是用del python.language可以解决
class Course: language = 'Chinese' def __init__(self, teacher, course_name, period, price): self.teacher = teacher self.name = course_name self.period = period self.price = price python = Course('Lisa','python','6 months',20000) linux = Course('Bob','linux','6 months',20000) python.language = 'English' print('Course:',Course.language) print('python: ',python.language) print('linux: ',linux.language) del python.language print('del 后 python: ',python.language) 输出结果: Course: Chinese python: English linux: Chinese del 后 python: Chinese
🌄五、动态属性修改知识点
上面的language = 'Chinese',中 'Chinese'是属于字符串是不可变的数据类型,如果换成language = [Chinese]这时列表是可变的数据类型,那么对动态属性修改与对静态属性的修改有什么区别呢?
代码一
class Course: language = ['Chinese'] def __init__(self, teacher, course_name, period, price): self.teacher = teacher self.name = course_name self.period = period self.price = price python = Course('Lisa','python','6 months',20000) linux = Course('Bob','linux','6 months',20000) Course.language[0] = 'English' print('Course:',Course.language) print('python: ',python.language) print('linux: ',linux.language) 输出结果: Course: ['English'] python: ['English'] linux: ['English']
代码二
class Course: language = ['Chinese'] def __init__(self, teacher, course_name, period, price): self.teacher = teacher self.name = course_name self.period = period self.price = price python = Course('Lisa','python','6 months',20000) linux = Course('Bob','linux','6 months',20000) python.language[0] = 'English' print('Course:',Course.language) print('python: ',python.language) print('linux: ',linux.language) 输出结果: Course: ['English'] python: ['English'] linux: ['English']
结果示意图
🌌1、小结
对于可变数据类型来说,对象名的修改是共享language[0] = 'Chinese'的, 重新赋值(language = 'Chinese')是独立的