开发者学堂课程【Python 入门 2020年版:__slots__属性的使用】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/639/detail/10369
__slots__属性的使用
内容介绍:
一、python 动态语言介绍
二、学习__slots__ 属性
一、python 动态语言介绍
在学习 python 语言中,存在一种情况,对于学过其他语言的人来说这个情况会比较怪异,python 语言是一种动态语言,有一个特点是叫动态类型。
在 07-self 语句的使用的代码基础上。
加入 print(s.name)
代码整体内容变为:
class Student(object):
def __init__(self,x,y):
self.name = x
self.age = y
def say_hello(self):
print(‘大家好,我是’,self.name)
s1 = Student(‘张三’,18)
s2 = Student(‘jack’, 21)
print(s1.name)
运行后的结果为:
把 s2 的内容删掉并加入已经有了 name、age 属性,这里可以调用 s.say_hello()
方法,加入 print(s.height)
在上图内存部分中可以看到,张三是不具备 height 属性
代码整体内容变为:
class Student(object):
def __init__(self,x,y):
self.name = x
self.age = y
def say_hello(self):
print(self.name)
s = Student(‘张三’,18)
print(s.name)
s.say_hello()
print(s.height)
运行后的结果为:
由于不具备 height 属性,直接运行会导致程序直接崩掉,这个地方显示的 AttributeError 是指属性的错误,后面的描述就是在警告 Student 这个对象中没有 height 属性,内存中只有 name、age 属性
以下的操作,在其它语言中不允许操作,但在 python 中是可以使用的。
在没有属性的情况下会报错,例如在代码中加入 s.city = ‘上海’、print(s.city)
语句。
代码变为如下:
class Student(object):
s = Student(‘张三’,18)
print(s.name)
s.say_hello()
s.city = ‘上海’
print(s.city)
运行后的结果为:
这时就会打印出上海
直接使用等号给一个属性赋值
如果这个属性以前不存在,就会给对象添加一个新的属性,刚刚的 s.city = ‘上海’就是给对象添加了一个 city 属性。
如果这个属性以前存在,会修改这个属性对应的值,例如在刚刚的代码中加入语句
s.name = ‘jack’
print(s.name)
这个就称为动态属性,没有什么属性就添加哪一个。在部分语言中是不允许的,原来定义了什么属性,后面只能改属性不能加属性,在 python 中是可以的。
二、学习__slots__ 属性
这样就涉及关于在 python 中怎样可以控制管理属性,这个功能是可以实现的,需要学习__slots__ 属性。
这个属性对应的是一个元组,这个属性直接定义在类中,他不在其他类中,是用来规定类中可以存在的属性。
(1)把__slots__ 加入到代码中,代码整体变为:
class Student(object):
__slots__ = ()
def __init__(self,x,y):
self.name = x
self.age = y
def say_hello(self):
print(self.name)
s = Student(‘张三’,18)
print(s.name)
s.say_hello()
s.city = ‘上海’
print(s.city)
s.name = ‘jack’
print(s.name)
通过观察注意到此时 self.name、self.age 行代码的颜色变为了橙色为背景颜色,如下图。
在 python 中,如果看到这样的橙色需要警惕,这说明书写的代码可能存在 bug,而且不管会导致后面出错。
将鼠标放置到 self.name、self.age
行代码可以看到上面会有一个方框提示说明这个 Student 类中没有这两个属性。
由于刚刚的代码中 __slots__ = ()
括号内为空,这时的内存空间中,这个地址下的属性中为空,一个属性都不能放进去。过程分析如图,什么都不能放,这种情况下会报错。
运行后的结果为:
结果显示不能使用。也就是__slots__ = () 规定了类中到底能放多少属性,括号内为空就是 0 个,括号内有几个就可以放几个属性。
(2)加入 name 属性,把语句改为__slots__ = (‘name‘,)
代码变为:
class Student(object):
__slots__ = (‘name’,)
def __init__(self,x,y):
self.name = x
self.age = y
def say_hello(self):
运行结果如下:
结果是 name 所在的行没有报错,但另一个 age 所在行报错,会显示没有 age 属性。所以需要什么属性就要在加入什么属性
(3)加入 age 属性,把语句改为__slots__ = (‘name‘,‘age’)
代码变为:
class Student(object):
__slots__ = (‘name’,‘age’)
def __init__(self,x,y):
self.name = x
self.age = y
def say_hello(self):
print(self.name)
运行结果如下:
由于不具备 city 属性,此时依旧报错
(4)加入 city 属性,把语句改为__slots__ = (‘name‘,‘age’,‘city’)
代码变为:
class Student(object):
__slots__ = (‘name’,‘age’,‘city’)
def __init__(self,x,y):
self.name = x
self.age = y
def say_hello(self):
print(self.name)
s = Student(‘张三’,18)
print(s.name)
s.say_hello()
s.city = ‘上海’
print(s.city)
s.name = ‘jack’
print(s.name)
总之没有在__slots__ = () 中写到的属性是不可以有的,否则会报错。