动态语言的灵活性,就是当我们定义一个class,创建class的实例后,可以给该实例绑定任何属性和方法。
定义一个Student类
class Student(object): def __init__(self): self
给实例绑定一个属性
# 创建一个实例 s = Student() # 动态给实例绑定属性 s.name = "rissa" print("name:%s" % s.name)
结果
name:rissa
需要定义一个函数作为实例方法,然后使用MethodType给实例绑定方法。
from types import MethodType class Student(object): def __init__(self): self # 定义一个函数作为实例方法 def set_score(self, score): self.score = score # 创建一个实例 s = Student() # 给实例动态绑定一个方法 s.set_score = MethodType(set_score, s) s.set_score("99") print("score:%s" % s.score)
结果
score:99
但是,给一个实例绑定的方法,对另一个实例是不起作用的
# 给实例动态绑定一个方法或属性后,对另一个实例不起作用 s2 = Student() s2.set_score("96") print("score:%s" % s2.score)
结果
为了给所有实例都绑定方法,可以给class绑定方法,给class绑定方法后,所有实例均可调用。
class Student(object): def __init__(self): self # 定义一个函数作为实例方法 def set_score(self, score): self.score = score # 给class绑定方法 Student.set_score = set_score # 创建实例 s = Student() s2 = Student() s.set_score("98") print("实例s:%s" % s.score) s2.set_score("96") print("实例s2:%s" % s2.score)
实例s:98
实例s2:96
当给实例动态绑定属性时,想要限制属性,使用__slots__变量来限制添加的属性。
class Student(object): def __init__(self): self __slots__ = ("name", "score") # 以元组的方式 # 创建一个实例 s = Student() # 动态给实例绑定属性 s.name = "rissa" print("name:%s" % s.name) s.score = "95" print("score:%s" % s.score) s.age = 18 print("age:%s" % s.age)
结果
由于“age”没有被放到__slots__中,所以绑定错误。
使用__slots__注意,__slots__定义的属性只对当前类实例有效,对继承的字类的实例是无用的,除非在子类中也定义__slots__。
在绑定属性时,我们直接把属性暴露出去,没办法检查参数,导致可以把属性会被随便更改。
我们可以使用setter和getter方法,在setter方法里面限制参数。
class Student(object): 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 s = Student() s.set_score(100) print("score:", s.get_score())
结果
score: 100
上述是调用方法的形式来访问类的变量,那么有没有既能检查参数,又可以用类似属性这样简单的方式来访问类的变量呢?需要使用Python内置的装饰器@property
负责把一个方法变成属性调用。
class Student(object): @property def score(self): return self._score @score.setter def 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 s = Student() s.score = 99 # 实际上转换成了set_score print("score:", s.score) # 实际上转换成了get_score
结果
score: 99
@property把一个getter方法变成了属性,然后又创建了另一个装饰器@score.setter负责把一个setter方法变成属性赋值
原文:https://www.cnblogs.com/rissa/p/15116393.html