# 正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。先定义class:
class Student(object):
pass
s=Student()
s.name='tom'
print(s.name)
# 还可以尝试给实例绑定一个方法:
def set_age(self,age):
self.age=age
from types import MethodType
s.set_age=MethodType(set_age,s) #给实例绑定一个方法
s.set_age(25) #调用实例方法
s.age #测试结果
# 但是,给一个实例绑定的方法,对另一个实例是不起作用的:
# 为了给所有实例都绑定方法,可以给class绑定方法:
def set_score(self,score):
self.score=score
Student.set_score=set_score
# 给class绑定方法后,所有实例均可调用:
s.set_score(100)
print(s.score)
# 但是,如果我们想要限制实例的属性怎么办?比如,只允许对Student实例添加name和age属性
class Student(object):
__slots__=('name','age') #用tuple 定义允许绑定的属性名字
#然后
s=Student() #创建新的实例
s.name='tom' #绑定属性name
s.age='25' #绑定属性age
s.score=99 #绑定属性score
# 由于'score'没有被放到__slots__中,所以不能绑定score属性,试图绑定score将得到AttributeError的错误。
# 使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的:
# 使用@property
# 在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改:
s = Student()
s.score = 9999
# 这显然不合逻辑。为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数:
class Student(object):
def __init__(self,score):
self.score=score
def get_score(self):
return self.score
def set_score(self,value):
if not isinstance(value,int):
raise ValueError('score must be an integer')
if value<0 or value>100:
raise ValueError('score must between 0 ~ 100!')
self._score = value
# 现在,对任意的Student实例进行操作,就不能随心所欲地设置score了:
s = Student()
s.set_score(60)
print(s.get_score())
# 但是,上面的调用方法又略显复杂,没有直接用属性这么直接简单。
# 有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?对于追求完美的Python程序员来说,这是必须要做到的!
# 还记得装饰器(decorator)可以给函数动态加上功能吗?对于类的方法,装饰器一样起作用。Python内置的@property装饰器就是负责把一个方法变成属性调用的:
python第10课 使用__slots__,@property
最新推荐文章于 2025-07-05 14:08:01 发布