Python_基础_(反射)

一,反射

1:反射:自省也称为反射,这个性质展示了某个对象是如何在运行期间取得自身的信息

2:如果传递一个对象给你,你应该可以查出该对象具有的能力,在Python中如果不具有自省能力,那么dir和type内建立的函数就无法正常的工作

3:反射指的是程序可以访问,检测,修改本身状态或行为的一种能力

 ## 四个可以实现自省的函数(适用于类和对象)

# 1:检测字符串name对应的属性或方法在不在对象Object中

hasattr(Object,name)

class Java:
    def __init__(self,name,size):
        self.name = name
        self.size = size

    def test_java(self):
        pass

j = Java("new_java",10)
print(hasattr(j,"name"))        # True  实际上找的是对象j能不能调用到属性name
print(hasattr(j,"test_java"))   # True  实际上找的是对象j能不能调用到属性test_java

 # 2:找到属性对应的值或找到函数对应的地址,如果不错在则报错

getattr(Object,name,default=None)

class Java:
    def __init__(self,name,size):
        self.name = name
        self.size = size

    def test_java(self):
        pass

j = Java("new_java",10)
print(getattr(j,"name"))        # new_java
print(getattr(j,"test_java"))   # <bound method Java.test_java of <__main__.Java object at 0x0000020152999470>>
print(getattr(j,"hello","不存在该参数"))      # 不存在该参数 当不存在时,则打印该参数

# 3:给对象添加一个属性,x:对象名,y:所要添加的属性名,v:属性的值

setattr(x,y,v)

class Java:
    def __init__(self,name,size):
        self.name = name
        self.size = size

    def test_java(self):
        pass

j = Java("new_java",10)

## 添加数据属性
setattr(j,"starttime","2018.1.1")   # 给对象添加属性starttime
print(j.__dict__)                   # {'name': 'new_java', 'size': 10, 'starttime': '2018.1.1'}

## 添加函数属性
setattr(j,"func",lambda x:x+1)
print(j.__dict__)                   # {'name': 'new_java', 'size': 10, 'starttime': '2018.1.1', 'func': <function <lambda> at 0x000002561C75B950>}

# 4:删掉对应的属性

delattr(x,y)

class Java:
    def __init__(self,name,size):
        self.name = name
        self.size = size

    def test_java(self):
        pass

j = Java("new_java",10)

delattr(j,"name")
print(j.__dict__)       # {'size': 10}

 ## 补充

class Test:
    def __init__(self,name):
        self.name = name

    def func():
        pass
    
    @staticmethod
    def func1():
        return "func1"
        

print( getattr(Test,"name") )
print( getattr(Test,"func") )

# 5:双下划线开头的attr  __getattr__  __setattr__  __delattr__

这戏额内置方法是给类实例化出来的对象使用的,类不能直接调用

# __getattr__

# 当一个对象调用一个不存在的属性时,__getattr__会执行
class Test:

    def __init__(self,name):
        self.name = name

    def __getattr__(self, item):
        print("执行了__getattr__方法,%s不存在" %item)
t = Test("henry")
t.x             # 执行了__getattr__方法,x不存在

# __delattr__

# 当删除对象自己的一个属性时,会调用 __delattr__
# 当删除非对象的属性时,也会执行 __delattr__
# 当在类中没有写入__delattr__方法,当执行del t.name时,会直接将该属性删除

 
# __delattr__用法1
class Test:

    def __init__(self,name):
        self.name = name

    def __delattr__(self, item):
        print("开始删除属性%s" %item)   # 开始删除属性name
        self.__dict__.pop(item)         # 删除itme

t = Test("henry")
del t.name
print(t.__dict__)       # {} 为空,name已经被删除

# __delattr__用法2
class Test:

    def __init__(self,name):
        self.name = name

    def __delattr__(self, item):
        print("不允许删除属性%s" %item)    # 不允许删除属性name

t = Test("henry")
del t.name
print(t.__dict__)       # {'name': 'henry'}

# __setattr__

# 当对象设置(新增,修改)属性时,setattr会被调用
class Test:

    def __init__(self,name):
        self.name = name

    def __setattr__(self, key, value):
        print("__setattr__被调用")

t = Test("henry")
t.username = "heihei"
# 输出
# __setattr__被调用  在实例化出对象的时调用一遍 t = Test("henry")
# __setattr__被调用

## __setattr__用法1
# 在进行属性添加时,判断属性的类型,再行
class Test:

    def __init__(self,name):
        self.name = name

    def __setattr__(self, key, value):
        if type(value) is str:
            self.__dict__[key] = value.upper()
        else:
            print("所添加属性值为非字符串,不进行添加")

t = Test("henry")
t.username = "heihei"
print(t.username)       # HEIHEI
二,包装

包装:包装通常是对已存在的类型的一些定制,这种做法可以新建,修改,删除原有产品的功能,其它的功能保存原样

授权:授权是包装的一个特性,授权的过程既是所有更新的功能都是由新类产生的某部分来处理

 # 使用继承方式完成的包装

class List(list):
    def append(self,P_object)
        if type(p_object) is str:
            super().append(p_object)
        else:
            print("只能添加字符串类型")
l1 = List("Hello World")
l1.append(18)       # 无法进行添加到主字符串中
l1.append("henry")    # 可以进行添加

 # 实现授权的关键点是覆盖方法 __getattr__

 待完成...

三,反射机制的作用

## 可插拔机制

## 动态导入模块 

原文地址:https://www.cnblogs.com/Doaoao/p/10153105.html