# slots限制
在类定义后,可以动态给实例对象绑定新的属性和方法。
```python
class Person(object):
def __init__(self, name, age):
self._name = name
self._age = age
```
创建一个实例并动态为这个实例绑定一个属性和方法,但是为实例绑定的属性和方法对另一个实例并不起作用,如果需要应用在多个实例上,则需要将其绑定到类上。
```python
from types import MethodType
def fly(self):
print('Fly now!')
def set_grade(self, grade):
self._grade = grade
p1 = Person('wang', 18)
p2 = Person('xiao', 16)
# 绑定一个属性
p1._gender
# 绑定一个方法
p1.fly = MethodType(fly, p1)
p1.fly()
# p1绑定的属性和方法对p2无效
p2._gender
p2.fly()
# 将属性和方法绑定到类上
Person._school = 'daxue'
# Person.set_grade = set_grade
Person.set_grade = MethodType(set_grade, Person)
p1._school
p1.set_grade('one')
```
动态绑定确实方便,但是如果我们需要限定自定义类型的对象只能绑定某些属性要怎么办呢?
```python
class Person(object):
# 我们限制只能对Person实例添加_name、_age、_gender属性
__slots__ = ('_name', '_age', '_gender')
def __init__(self, name, age):
self.name = name
self.age = age
```
实例就不能再添加不在限定范围内的属性了
```python
p3 = Person('qqq', 7)
p3._gender = 'nan'
p3._school = 'xiaoxue'
# AttributeError
p.fly = MethodType(fly, p)
# AttributeError
```
但要注意的是,限制只是针对实例,类本身并不会被限制。就是我们仍然可以通过类去添加属性或方法
```python
Person._school = 'xiaoxue'
p3._school
Person.fly = fly
p3.fly()
Person.set_grade = MethodType(set_grade, Person)
p3.set_grade('2')
# 同时需要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
```