反射:
反射:通过字符串去操作对象(类,空间等等)的属性或方法
反射的四个方法
hasattr ***
getattr ***
setattr ***
delattr ***
# getattr 用法
class A: role = '太白' def func(self): print(666) conter = input('请输入: ') #str类型 输入role ret = getattr(A,conter) # 即使conter = 'role'字符串的role,A.role也可以找到 print(ret)
hasattr, getattr, setattr, delattr 用法示例
# 操作对象的角度
class A: country = 'China' area = '深圳' def __init__(self,name,age): self.name = name self.age = age def func(self): print(666) # obj = A('忠敏',18) # print(obj.name) # 忠敏 print(hasattr(obj,'name')) # True 判断对象有没有此属性 if hasattr(obj,'name'): print(getattr(obj,'name')) # 相当于 print(obj.name) print(getattr(obj,'sex',None)) # 获得obj的sex值,如果没有则返回None print(obj.country) print(getattr(obj,'country')) # 可以获得类的静态属性 obj.func() ret = getattr(obj, 'func') # ret = func的内存地址 print(ret) ret() print(obj.sex) # 没有改属性,报错 setattr(obj,'sex','男') # 设置sex = '男' print(obj.sex) delattr(obj,'name') # 删除该属性 print(obj.name)
操作类的角度
class A: country = 'China' area = '深圳' def __init__(self,name,age): self.name = name self.age = age def func(self): print(666) print(getattr(A,'country')) # print(getattr(A,'area')) print(getattr(A,'name)) # name是对象的属性,类找不到 getattr(A,'func')(23) # 可以执行类的方法 print(hasattr(A,'func2')) # False 没有func2
操作另一个py文件
import attr # attr.py print(getattr(attr,'flag')) # 1,找到func 并执行 ret = getattr(attr,'func') print(ret(10)) #2,找到B类并调用 name_list func函数 b = getattr(attr,'B') print(b.name_list)
本文件操作
import sys obj = sys.modules[__name__] # obj = 本py文件 print(obj) # def func(): # print(666) # # ret = input('>>>') # 输入func # # ret() # 无法执行func() # getattr(obj,ret)() # 可以执行func() def func1(): print('in func1') def func2(): print('in func2') def func3(): print('in func3') l1 = ['func%s' % i for i in range(1,4)] # l1 = ['func1', 'func2', 'func3'] print(l1) # print(l1) for i in l1: # i = 'func1' 字符串 getattr(obj,i)()
到底什么对象才可以用反射?
实例化对象 类 其他模块 本模块 只有能通过.的方式获取的,才可以用反射。(函数不能使用反射)
双下方法:(含有两个下划线)
双下方法是给python源码的开发者用
s1 = 'saekfjldkjase' print(len(s1)) # 相当于 s1.__len__() print(s1.__len__())
isinstance 判断此对象是不是该类(或者是该类的子类)实例化的对象
class A: pass class B(A): pass obj = A() print(isinstance(obj,A)) # True print(isinstance(obj,B)) # False
issubclass 判断的是此类是不是后面类的派生类
class D: pass class A(D): pass class B(A): pass print(issubclass(B,A)) #True print(issubclass(B,D)) #True
特殊双下方法:
# __len__ 方法 class A: def __init__(self,name,age): self.name = name self.age = age self.sex = '男' def __len__(self): # print(666) return len(self.__dict__) # 返回字典的长度 a = A('barry', 18) len(a) # len(对象) 如果此类中有__len__ 方法会自动执行__len__ print(len(a))
__hash__ __str__
class A: def __init__(self,name,age): self.name = name self.age = age self.sex = '男' def __len__(self): # print(666) return len(self.__dict__) def __hash__(self): return 1 def __str__(self): print(555) return 'fdsaf' # object a = A('barry', 18) print(hash(a)) # 定义了__hash__方法,所以自动执行 print(a,type(a)) # 对一个对象打印时,自动触发类中的__str__方法
__call__ 方法: 对象(),会触发 __call__ 方法
class Foo: def __init__(self): print(11) def __call__(self, *args, **kwargs): print(123) obj = Foo() obj() # 对象() 触发 __call__方法
__new__ 方法,实例化对象发生的三件事
1, 类名() 执行object.__new__方法,开辟对象空间并返回
2,自动执行__init__方法,将空间创给self
3,在__init__给对象封装属性
class A: def __init__(self,name): self.name = name print('in A __init__') def __new__(cls, *args, **kwargs): # 自定义了一个__new__方法 print('in A __new__') return object.__new__(cls) # 返回一个python内置的__new__方法 a = A('春哥') print(a.name)
单例模式: 让一个类只能实例化一个对象
class A(): __instance = None def __init__(self,name,age): self.name = name self.age = age def __new__(cls, *args, **kwargs): if cls.__instance is None: obj = object.__new__(cls) cls.__instance = obj return cls.__instance
item系列将对象视为字典使用时,就会触发item方法
class Foo: def __init__(self,name): self.name = name def __getitem__(self, item): # print(666) return self.name # print(self.__dict__[item]) def __setitem__(self, key, value): # print(key) # print(value) self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item) f1 = Foo('sb') ret = f1['name'] print(ret) # f1['age'] = 12 # # print(f1.__dict__) # print(f1.age) # # # f1['age']=18 # f1['age1']=19 # del f1.age1 # del f1['age'] # f1['name']='alex' # print(f1.__dict__)