动态添加属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Person(object): def __init__:(self,name,age) self.name = name self.age = age
a1 = Person("a1",100) print(a1.name) print(a1.age) # 给a1添加属性 a1.addr = 'beijing' print(a1.addr)
b1 = Person("b1",1000) print(b1.name) print(b1.age)
# print(b1.addr) 报错 因为 addr是a1对象动态添加的属性,仅跟对象绑定
# 类属性 Person.num = 100
print(a1.num) #100 print(b1.num) #100
|
动态添加方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Person(object): def __init__:(self,name,age) self.name = name self.age = age def eat(self): print("%s正在吃"%self.name)
# run不在 Person类中定义 def run(self): print("--------%s正在跑-----"%self.name)
p1 = Person('p1',10) p1.eat()
#错误方式1 # p1.run() 报错
#错误方式2 (把方法地址传递给 p1.run属性) #虽然p1对象中,run属性已经指向了 外部 run方法的地址 #因为run属性指向的函数是后来添加的,执行p1.run()的时候,并没有把p1当作第一个参数,所以在调用的时候出现却缺少参数 # p1.run = run
|
正确的做法是
1 2 3 4 5 6 7 8 9 10
| import types
''' types.MethodType(method,instance) 可以实现对对象添加动态方法 '''
p1.run = types.MethodType(run,p1) p1.run() # 不报错 !!! # p1正在吃
|
types.MethodType深入
如果我们这样发现可以直接调用
1 2 3
| xxxx = types.MethodType(run,p1) xxxx() # p1正在吃
|
- types.MethodType(run,p1) 实际是把实例对象传递到普通方法run里缺少的self参数
- types.MethodType(run,p1) 返回的实际就是那个传递了参数的run方法的引用
1 2 3 4 5
| def run(self): print(self.name)
def run(p1): print(p1.name)
|
静态方法添加
1 2 3 4 5 6 7 8 9
| @staticMethod def test(): print('-----static method ------')
# 静态方法可以直接添加因为没有self参数 Person.test = test;
Person.test()
|
类方法
1 2 3 4 5 6 7
| @classMethod def test2(cls): print('-----class method ------')
Person.test2 = test2
Person.test2()
|
slots作用
因为python是动态语言所以在实例生成之后仍然可以额外添加属性
如何做到让它添加指定的属性呢
slots
1 2 3 4 5 6 7 8
| class Person(object): __slots__ = ("name","age")
p1 = Person() p1.name = 'aa' # 正常 p1.age = 20 # 正常 p1.num =1000 # 报错
|