4.反射
一 isinstance,type,issubclass
class Animal: def eat(self): print("刚睡醒吃点东西") class Cat(Animal): def play(self): print("猫喜欢玩") c = Cat() print(isinstance(c,Cat))#True print(isinstance(c,Animal)) #True print(type(c))#<class '__main__.Cat'>
type判断数据类型先判断好要计算的数据类型必须是int或者float. 这样的计算才有意义
def cul(a,b): if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float): return a + b else: print("对不起.你提供的数据不存在") print(cul(1,2))
通过对象调用@classmethod的是方法,@statimethod的是函数
class Foo: def chi(self): print("我能吃") @staticmethod def static_method(): pass @classmethod def class_method(cls): pass f = Foo() print(f.chi)#<bound method Foo.chi of <__main__.Foo object at 0x00000231A803DC50>> print(Foo.chi)#<function Foo.chi at 0x00000231A81B4AE8> print(f.static_method)#<function Foo.static_method at 0x00000231A81B4C80> print(Foo.static_method)#function Foo.static_method at 0x00000231A81B4C80> print(f.class_method)#<bound method Foo.class_method of <class '__main__.Foo'>> print(Foo.class_method)#<bound method Foo.class_method of <class '__main__.Foo'>>
结论:
1. 类方法. 不论任何情况, 都是方法.
2. 静态方法, 不论任何情况. 都是函数
3. 实例方法, 如果是实例访问. 就是方法. 如果是类名访问就是函数.
from types import MethodType,FunctionType def func(): pass print(isinstance(func,FunctionType))#True print(isinstance(func,MethodType))#False class Foo: def chi(self): print("我能吃") @staticmethod def static_method(): pass @classmethod def class_method(cls): pass obj = Foo() print(type(obj.chi))#<class 'method'> print(type(Foo.chi))#<class 'function'> print(isinstance(obj.chi,MethodType))#True print(isinstance(obj.chi,FunctionType))#False print(isinstance(Foo.static_method,FunctionType))#True print(isinstance(Foo.static_method,MethodType))#False print(isinstance(Foo.class_method,FunctionType))#False print(isinstance(Foo.class_method,MethodType)) #True
小题目
class Foo: @classmethod def func1(cls): pass @staticmethod def func2(self): pass def func3(self): pass def func4(self): pass lst = [func1,func2,func3] obj = Foo() # Foo.lst.append(obj.func4) # for item in Foo.lst: print(isinstance(item,MethodType)) print(item)
结果
False <classmethod object at 0x000002090B72DDA0> False <staticmethod object at 0x000002090B72DE80> False <function Foo.func3 at 0x000002090B8A4EA0> True <bound method Foo.func4 of <__main__.Foo object at 0x000002090B72D8D0>>
反射
先创建master.py
def chi(): print("大牛太能吃") def he(): print("大牛一次喝一桶") def shui(): print("大牛一睡睡一年") def play(): print("大牛不玩压缩包") def sa(): print("大牛很能撒谎") def la(): print("大牛喜欢拉二胡")
然后执行以下代码
import master while 1: content = input("请输入你要测试的功能") if hasattr(master,content): s = getattr(master,content) s() print("有这个功能") else: print("没有这个功能")
getattr可以从模块中获取内容, 也可以从类中获取内容, 也可以从对象中获取内容. 在python中一切皆为对象. 那可以这样认为. getattr从对象中动态的获取成员
反射使用的常用函数:
hasattr()
用于判断对象是否包含对应的属性
getattr()
获取对象object的属性或者方法,如果存在打印出来,如果不存在,打印出默认值,默认值可选。
需要注意的是,如果是返回的对象的方法,返回的是方法的内存地址,如果需要运行这个方法,
可以在后面添加一对括号,getattr(变量名:命名空间,字符串:属于一个命名类的变量名)
setattr()
给对象的属性赋值,若属性不存在,先创建再赋值,setattr() 接收三个参数,命名空间,‘变量名’,变量值
delattr()
删除 object对象 中的 name属性
class Foo: pass f= Foo() print(hasattr(f,"chi"))#False setattr(f,"chi","123") print(f.chi)#123 setattr(f,"chi",lambda x:x+1) print(f.chi(3)) #4 print(f.chi)#<function <lambda> at 0x0000016718DE4D90> print(f.__dict__)#{'chi': <function <lambda> at 0x00000192D2194D08>} delattr(f,"chi") print(hasattr(f,"chi"))#False
1. hasattr(obj, str) 判断obj中是否包含str成员
2. getattr(obj,str) 从obj中获取str成员
3. setattr(obj, str, value) 把obj中的str成员设置成value. 注意. 这里的value可以是值, 也可以是函数或者方法
4. delattr(obj, str) 把obj中的str成员删除掉
class Person: def __init__(self,name,laopo): self.name = name self.laopo = laopo p= Person("宝宝","林志玲") print(hasattr(p,"laopo")) print(getattr(p,"laopo")) setattr(p,"laopo","胡一菲") setattr(p,"money",100000) print(p.laopo) print(p.money) delattr(p,"laopo") print(p.laopo)