zoukankan      html  css  js  c++  java
  • 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__

     待完成...

    三,反射机制的作用

    ## 可插拔机制

    ## 动态导入模块 

  • 相关阅读:
    dll得到主窗體的handle
    将应用程序11M内存占用,降至500K
    是否想为你的Windows加上一双眼睛,察看使用者在机器上所做的各种操作(例如建立、删除文件;改变文件或目录名字)呢?
    TreeView 之间节点拖动 /移动
    Delphi与C之间的类型对应表
    以ADO数据集相连的DBGrid按单一字段排序通用过程
    为Delphi程序添加事件和事件处理器
    DataSetToTreeView
    一个系统空闲时间函数
    调用chm
  • 原文地址:https://www.cnblogs.com/Doaoao/p/10153105.html
Copyright © 2011-2022 走看看