类和对象的动态变换
在 Python 中比较特殊的是,可以动态地为自定义类和对象增加或删除成员这一点是和很多面向对象程序设计语言不同的,也是 Python 动态类型特点的一种重要体现。
动态增加数据成员
看个例子
class Car: price=100000 #定义类属性 def __init__(self,c) self.color=c #定义示例属性car1=Car("Red") #实例化对象car2=Car("Blue")print(car1.color,Car.price) #查看实例属性和类属性的值Car.price=110000 #修改类属性Car.name ='QQ' #动态增加类属性car1.color ="Yellow" #修改实例属性print(car2.color,Car.price,Car.name) print(car1.color,Car.price,Car.name)复制代码
复制代码
name是使用过程中动态增加的。
动态增加的函数
看个例子
import typesdef setspeed(self,s): self.speed =scar1.setspeed=types.MethodType(setspeed,car1) #动态增加成员方法car1.setspeed(50) #调用成员方法print(car1.speed)复制代码
复制代码
导入types模块,因为需要使用types.MethodType ,用于导入新的成员方法。例如,
car1.setspeed=types.MethodType(setspeed,car1)复制代码
复制代码
将前面的car1增加新的成员方法setspeed ,后续直接使用setspeed 的成员方法。
Python 类型的动态性使得我们可以动态为自定义类及其对象增加新的属性和行为,俗称混入机制,这在大型项目开发中会非常方便和实用。
案例演示
>>> import types>>> class Person(object): def __init__(self, name): assert isinstance(name, str), 'name must be string ' self.name=name>>> def sing(self): print(self.name+' can sing.')>>> def walk(self): print(self.name+' can walk.')>>> def eat(self): print(self.name+' can eat.')复制代码
复制代码
assert isinstance用于判断变量类型。例如这个,判断name是否是字符串(str ),如果是字符串,往下执行;如果不是字符串,则不继续执行并返回'name must be string ' 。
错误示范:未加入就调用
>>> zhang =Person('zhang') >>> zhang.sing() #用户不具有该行为AttributeError: 'Person’ object has no attribute 'sing'复制代码
复制代码
现在person中没有引用sing函数,这样使用是错误的。
正确示范:把 sing 加入 zhang 中
>>> zhang.sing =types.MethodType(sing,zhang) #动态增加一个新行为>>> zhang.sing() zhang can sing.复制代码
复制代码
与sing建立关联,可以调用sing函数。例如下面这个,walk未调用就直接引用就会出错。
>>> zhang.walk()AttributeError: 'Person’ object has no attribute 'walk!复制代码
复制代码
删除信息
>>> del zhang.walk #删除用户行为 >>> zhang.walk(()AttributeError: 'Person’ obiect has no attribute 'walk'复制代码
复制代码
用del即可删除zhang的用户行为,再次调用就会出错。
评论