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__

     待完成...

    三,反射机制的作用

    ## 可插拔机制

    ## 动态导入模块 

  • 相关阅读:
    HDOJ 1207 汉诺塔II
    [转]写代码的小女孩
    POJ Subway tree systems
    HDOJ 3555 Bomb (数位DP)
    POJ 1636 Prison rearrangement (DP)
    POJ 1015 Jury Compromise (DP)
    UVA 10003
    UVA 103 Stacking Boxes
    HDOJ 3530 Subsequence
    第三百六十二、三天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/Doaoao/p/10153105.html
Copyright © 2011-2022 走看看