八. 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()  # 执行该函数



原文地址:https://www.cnblogs.com/Sup-to/p/10884341.html