前面学习了类属性和实例属性,我们已经知道:实例属性属于各个实例对象所有,互不干扰;类属性属于类所有,所有实例共享一个属性。我们设计一个Car
类:
# 定义一个Car类
class Car(object):
pass
# 创建Car类的一个实例
c = Car()
# 给实例c绑定对象属性speed,并赋值:200
c.speed = 200
# 创建Car类的一个实例
c2 = Car()
print(c2.speed)
运行结果:
Traceback (most recent call last):
File "F:/python_projects/oop/25Car.py", line 15, in <module>
print(c2.speed)
AttributeError: 'Car' object has no attribute 'speed'
这里的speed
属性只属于c
对象。Car
类中没有speed
类属性,如果该类的其他对象(比如c2)在绑定speed
属性前,则没有该属性,所以直接访问c2.speed会报错:AttributeError: 'Car' object has no attribute 'speed'
通常,如果某个对象需要某个属性、方法,我们可以直接给其绑定属性、方法,但是,给一个实例绑定的属性、方法,对另一个实例是不起作用的,如上面的例子中的speed
属性。
为了给所有实例都绑定属性、方法,可以给类Car绑定属性、方法。
现在我们还可以随意地给对象c3
绑定一些测试属性:x, y, z
:
c3 = Car()
c3.x = 'x'
c3.y = 'y'
c3.z = 'z'
print(c3.x)
print(c3.y)
print(c3.z)
运行结果:
x
y
z
那么问题来了:如果我想要限制实例的属性怎么办?比如,只允许对Car实例添加speed
和color
属性。这就需要用到限制对象属性的属性了:__slots__
限制实例属性的属性__slots__
slots
:本意是:狭孔、插板上的插槽等。此处表示
只需要在定义类时添加如下代码:__slots__ = 'speed', 'color'
即可,只允许对Car实例添加speed
和color
属性。Car类定义更新如下:
# 定义一个Car类
class Car(object):
# 表示只允许对Car实例添加speed和color属性。
__slots__ = 'speed', 'color'
pass
同样再次随意绑定其他属性x
,测试如下:
# 创建一个Car类对象
c3 = Car()
# 随意绑定一个属性x,并赋值‘x’
c3.x = 'x'
print(c3.x)
运行结果:
Traceback (most recent call last):
File "F:/python_projects/oop/25Car.py", line 13, in <module>
c.x = 'x'
AttributeError: 'Car' object has no attribute 'x'
这是由于'x'没有被放到__slots__
中,所以不能绑定x
属性,试图绑定x
将得到AttributeError
的错误。
如果,我们不是添加x
,而是对Car实例添加speed
和color
属性:
# 定义一个Car类
class Car(object):
__slots__ = 'speed', 'color'
pass
# 创建Car类的一个实例
c = Car()
# 对Car类对象绑定speed\color属性:
c.speed = '200'
c.color = 'red'
print(c.speed)
print(c.color)
运行结果:
200
red
小结及注意
1.使用__slots__
要注意,__slots__
定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。
定义一个大众汽车类DaZhong
,继承自Car类,并对DaZhong类的一个实例绑定除speed\color之外的属性,比如:logo属性,代码如下:
# 定义一个Car类
class Car(object):
__slots__ = 'speed', 'color'
pass
# 定义一个大众汽车类,继承自Car:
class DaZhong(Car):
pass
# 创建DaZhong类的一个实例
d = DaZhong()
# 对DaZhong类对象绑定除speed\color之外的属性,比如:logo
d.logo = "DaZhong's logo"
print(d.logo)
运行结果:
DaZhong's logo
可以绑定成功。验证了:__slots__
定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。除非在子类中也定义__slots__
,这样,子类实例允许定义的属性就是自身的__slots__
加上父类的__slots__
。
2.__slots__
限制的是类的实例的属性,且不能和类属性有重名的,否则报错。
# 定义一个Car类
class Car(object):
__slots__ = 'speed', 'color'
color = 'white'
pass
运行结果:
Traceback (most recent call last):
File "F:/python_projects/oop/25Car.py", line 2, in <module>
class Car(object):
ValueError: 'color' in __slots__ conflicts with class variable
ValueError: 'color' in __slots__ conflicts with class variable
意思是: 值错误:__slots__里面的color属性和类属性color冲突了
。
更多了解,可关注公众号:人人懂编程
![](https://img.haomeiwen.com/i2471034/0dce8137109d82b4.png)
网友评论