八. python面向对象(反射和内置方法)
一 . 反射
# 反射:是用字符串类型的名字 取获取变量方法操作
# hasattr()
# getattr()
# delattr()
# setattr()
# isinstance(obj,cls) 检查是否obj是否是类 cls的对象 class Lo(object): pass aa=Lo() print(isinstance(aa,Lo)) # issubclass(sub,super) 检查sub类是否是super的派生类(子类) class A:pass class B(A):pass print(issubclass(B,A)) print(issubclass(A,B))
1.getattr
class Da(object): cc="188888" def __init__(self,name): self.name=name def aa(self): print("反射!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11") f=Da("张三") cc=getattr(f,'aa') cc() print("**********************************************") f.aa()
class A: def fun(self): print("哈哈哈哈哈哈!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") a=A() a.name="张三" a.age=25 # 反射对象的属性 ret=getattr(a,"name") # 通过字符串取到的值 print(ret) print("**********************") # 反射对象的方法 r=getattr(a,"fun") r() print(a.__dict__)
# 反射类的方法 classmethod staticmethod class B: bb=20 @classmethod def fun(self): print("!!!!!!!!!!") print(B.bb)# 20 # 反射类属性 ret=getattr(B,"bb") print(ret)# 20 # 反射类方法 re=getattr(B,"fun") re() # !!!!!!!!!!
反射模块
# my.py 文件 day='Monday' # 周一 def Gun(): print("模块中!!!!!!!!!!!!!!反射")
# 模块 # 反射模块的属性 import my r=getattr(my,"day") print(r) # 反射模块的方法 ret=getattr(my,'Gun') ret()
import sys # 内置模块也能用 # 反射自己模块中的变量(就是本模块) def Gn(): print("44444444444444") ye=1111111111 print(sys.modules['__main__'].ye) k=getattr(sys.modules['__main__'],"ye") print(k) # 反射自己模块中的方法(函数) t=getattr(sys.modules['__main__'],"Gn") t() ff=input(">>>>") gg=getattr(sys.modules['__main__'],ff) print(gg)
二.
# 把自己变成自己的模块
import sys
aa=sys.modules[__name__]
print(aa)
x=122222222222
print(hasattr(aa,"x"))
# True
print(getattr(aa,"x"))
# 122222222222
二. 内置方法
2.__delattr__
__delattr__ 删除一个会促发这个方法
class Foo(object): x=1 def __init__(self,y): self.y=y def __delattr__ (self,item): print("执行 __delattr__ 方法") a1=Foo(10) del a1.y # 执行 __delattr__ 方法 del a1.x
3.__setattr__
# __setattr__ 设置属性时会促发 __setattr__
ass Foo(object): x = 1 def __init__(self, y): self.y = y def __setattr__(self, key, value): # self.key=value # 这样设置是不行的 self.__dict__[key] = value print("执行 __setattr__ 方法") a1 = Foo(10) print(a1.__dict__) # 执行 __setattr__ 方法 # {'y': 10} a1.z = 10000 print(a1.__dict__) # 执行 __setattr__ 方法 # {'y': 10, 'z': 10000}
# __setattr__ 设置属性时会促发 __setattr__ class Foo(object): def __init__(self,name): self.name=name def __setattr__(self,key,value): self.__dict__[key]=value print("执行__setattr__方法",key,value) a2=Foo("张三") a2.age="25岁" a2.sex="男" print(a1.__dict__) """执行__setattr__方法 name 张三 执行__setattr__方法 age 25岁 执行__setattr__方法 sex 男 {'name': '张三'}"""
# class Faa(object): def __init__(self,name): self.name=name def __setattr__(self,key,value): if type(value) is str: print("执行__setattr__方法",key,value) self.__dict__[key]=value else: print("必须是字符串") a3=Faa("张三") a3.age="25岁" a3.sex="男" a3.shenggao=188 # type 是数字就添加不进去 print(a3.__dict__) """执行__setattr__方法 name 张三 执行__setattr__方法 age 25岁 执行__setattr__方法 sex 男 {'name': '张三', 'age': '25岁', 'sex': '男'}"""
4. __getattr__
# __getattr__ 调用你一个对象不存在的属性才会促发 但是不会报错 class Fo(object): def __init__(self, name): self.name = name def __getattr__(self, item): print("你找的属性[%s]不存在" % item) a1 = Fo("张三") print(a1.name) print(a1.age) """张三 你找的属性[age]不存在 None"""
class Foo(object): x = 1 def __init__(self, y): self.y = y def __getattr__(self, item): print("执行__getattr__方法") a1 = Foo(10) print(a1.y) # 10 print(getattr(a1, 'y')) # 10 a1.ddddddddddddddddddddddddd # 执行__getattr__方法
class Get(object): pass print(Get.__dict__) # {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Get' objects>, '__weakref__': <attribute '__weakref__' of 'Get' objects>, '__doc__': None} print(dir(Get)) # ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
# __delattr__ 删除一个会促发这个方法 class Fa(object): def __init__(self,name): self.name=name def __setattr__(self,key,value): if type(value) is str: print("执行__setattr__方法",key,value) self.__dict__[key]=value else: print("必须是字符串") def __delattr__ (self,item): print("执行 __delattr__ 方法",item) a4=Fa("张三") a4.age="25岁" a4.sex="男" a4.shenggao=188 # type 是数字就添加不进去 print(a3.__dict__) del a4.name """执行__setattr__方法 name 张三 执行__setattr__方法 age 25岁 执行__setattr__方法 sex 男 必须是字符串 {'name': '张三', 'age': '25岁', 'sex': '男'} 执行 __delattr__ 方法 name """
# __getattr__ __setattr__ __delattr__ class Da(object): def __init__(self,al,we): self.al=al self.we=we def aa(self): print(11111111111111111) # 获取没有的属性触发 def __getattr__(self, item): print(item) print("当对象调用类里面没有的属性才会触发 __getattr__") # 设置触发 def __setattr__(self, key, value): print(key,value,"------这是设置就会触发__setattr__") # 删除触发 def __delattr__(self, item): print(item,"删除就触发他吧") cc = Da("张三",5555) cc.bb # bb # 当对象调用类里面没有的属性才会触发 __getattr__ print("**************************************************************************") del cc.al # al 张三 ------这是设置就会触发__setattr__ # we 5555 ------这是设置就会触发__setattr__ # bb # 当对象调用类里面没有的属性才会触发 __getattr__ # ************************************************************************** # al 删除就触发他吧
查看方法 或者是函数 class Da(object): def aa(self): print(11111111111111111) cc = Da() # <class 'method'> # <class 'function'>
这是 aa.py def f1(): print("f1") def f2(): print("f2") def f3(): print("f4") def f5(): print("f5") a=1
import aa print(hasattr(aa,"a")) # True print(hasattr(aa,"bb")) # False vv=setattr(aa,"a",999) print(vv) # None print(getattr(aa,"a")) # 999 setattr(aa,"f1",lambda x:x+1) f=getattr(aa,"f1") p=f(1) print(p) # 2
from types import FunctionType # # 判断是否是个函数 import aa while True: inu=input("输入你想要实现的功能啊哈哈哈哈") if hasattr(aa,inu): bb=getattr(aa,inu) if isinstance(bb,FunctionType): bb() else: print(bb) else: print("输入的函数模块中没有")
class Dog(object): ret = ["aa", "bb", "cc"] lover="你妹的" def __init__(self,name,age): self.name=name self.age=age def aa(self): print("111111111111111111") def bb(self): print("22222222222222222") def cc(self): print(self.lover) def run(self): while True: spek=input("输入列表中>>>>").strip() for i in self.ret: if i ==spek: g=getattr(self,spek) g() break else: print("输入错误了") cc=Dog("金毛",55) cc.run()
class Dog(object): ret = ["aa", "bb", "cc"] lover = "你妹的" def __init__(self, name, age): self.name = name self.age = age def aa(self): print("111111111111111111") def bb(self): print("22222222222222222") def cc(self): print(self.lover) def run(self): while True: spek = input("输入列表中>>>>").strip() if spek in self.ret: f = getattr(self, spek) f() else: print("你输入的有误哈哈哈") cc = Dog("金毛", 55) cc.run()
# 利用反射动态导入模块 执行模块中的函数 imp = input("请输入你想导入的模块名:") CC = __import__(imp) # 這种方式就是通过输入字符串导入你所想导入的模块 CC.f1() # 执行模块中的f1方法 print("******************************************") imp = input("请输入模块:") dd = __import__(imp) # 等价于import imp inp_func = input("请输入要执行的函数:") f = getattr(dd, inp_func,None) # 作用:从导入模块中找到你需要调用的函数inp_func,然后返回一个该函数的引用.没有找到就烦会None f() # 执行该函数