__slots__的食用方式

动态语言中通过class创建了实例后,可以给该实例绑定任何方法和属性

class Student(object):
    pass
# 绑定一个属性
s = Student()
s.name = 'Michael' # 动态的给实例绑定一个属性
print(s.name)

def set_age(self, age): # 定义一个函数作为实例(java中叫成员)方法
    self.age = age
        
#  再给Student绑定一个方法    
from types import MethodType
s.set_age_new = MethodType(set_age, s)  # 给实例绑定一个方法
s.set_age_new(25)  # 调用实例方法
print(s.age) # 测试结果

# 但是绑定的方法,对其他的实例不起作用
s2 = Student() # 创建新实例
#  AttributeError: 'Student' object has no attribute 'set_age_new'
# s2.set_age_new(23) # 调用绑定的实例方法

# 为了给所有实例都绑定方法,可以给class绑定方法
def set_score(self, socre):
    self.socre = socre

Student.set_score_new = set_score # 为class绑定方法

# 绑定后, 所有的实例都可以调用
s.set_score_new(100)
print(s.socre)
s2.set_score_new(99)
print(s2.socre)
Michael
25
100
99

通常上面set_score() 方法是直接定义在class中,但动态绑定在 允许程序运行过程中给class加上功能,这在静态语言中很难实现

__slots__

如果需要限制属性.比如值允许对Student实例中添加nameage属性,为了实现这一个目的python运行在定义class的时候定义一个特殊的变量__slots__,来限制class实例能添加的属性

class Student(object):
    __slots__ = ('name', 'age') # 用tuple定义运行绑定的属性名称

s = Student()  # 创建新的实例
s.name = 'Michael'  # 绑定属性name
s.age = 25  # 绑定属性age
#  AttributeError: 'Student' object has no attribute 'score'
# s.score = 99

# tips: 在定义__slots__要注意, 该属性进队当前类的实例起作用,对继承的子类是不起作用的
class GraduateStudent(Student):
    pass
g = GraduateStudent()
g.score = 9999

除非在子类也定义了__slots__,子类实例运行定义的属性就是自身的__slots__加上父类__slots__

猜你喜欢

转载自www.cnblogs.com/codycc/p/9880449.html