zoukankan      html  css  js  c++  java
  • python之反射

    isinstance(obj,cls)检查obj是否是类的对象

    class Foo(object):
    
        pass
    
    obj=Foo()
    
    print(isinstance(obj,Foo))
    
    >> 
    
    True
    
     
    

      

    Issubclass(sub,super)检查sub类是否是super类的派生类

    class Foo(object):
    
        pass
    
    class Bar(Foo):
    
        pass
    
    print(issubclass(Bar,Foo))
    
    >> 
    
    True
    

      

    反射的概念:指程序可以访问、检测和修改它本身2状态或行为的一种能力(自省)。

    Python面向对象中的反射:通过字符串的形式操作对象相关的属性。Python中的一切事物都是对象(都可以使用反射)

    四个可以实现自省的函数

    方法适用于类和对象(一切皆对象,类本身也是一个对象)

    hasattr 判断object中有没有一个name字符串对应的方法或属性

    hasattr(object,name)查看对象的__dict__是否有这个值,返回bool值

    检测是否含有某属性

    格式:print(hasattr(x,y))

    class People:
    
        country="China"
    
        def __init__(self,name):
    
            self.name=name
    
        def walk(self):
    
            print("%s is walking"%self.name)
    
    p=People("karina")
    
    print(hasattr(p,"name"))
    
    >> 
    
    True
    

      

    gatattr 获取属性

    格式:res=getattr(x,y)

    print(res)

    lass People:
    
        country="China"
    
        def __init__(self,name):
    
            self.name=name
    
        def walk(self):
    
            print("%s is walking"%self.name)
    
    p=People("karina")
    
     
    
    print(getattr(p,"name"))
    
    >> 
    
    karina
    

      

    setattr 设置属性

    格式:setattr(x,y,z)

    print(x.__dict__)

    class People:
    
        country="China"
    
        def __init__(self,name):
    
            self.name=name
    
        def walk(self):
    
            print("%s is walking"%self.name)
    
    p=People("karina")
    
    setattr(p,"age",18)#setattr(x,y,z)分别传入对象,属性,值
    
    print(p.__dict__)
    
    print(p.age)
    
     
    
    #p.sex="female"  #设置一个性别
    
    #print(p.sex) #打印
    
    #print(p.__dict__)#查看对象对应字典中的信息
    
    >> 
    
    female
    
    {'name': 'karina', 'sex': 'female'}#字典中已经添加性别这个键值对
    

      

    delattr 删除属性

    格式:delattr(x,y)

          Delattr(x,y1111)#不存在,则报错

          Print(x.__dict__)

    class People:
    
        country="China"
    
        def __init__(self,name):
    
            self.name=name
    
        def walk(self):
    
            print("%s is walking"%self.name)
    
    p=People("karina")
    
     
    
    delattr(p,"name") #删除对象的name
    
    # print(p.name)
    
    print(p.__dict__)#查看对象对应的字典信息
    
    >> 
    
    {}
    

      

    使用反射的好处

    1.      实现可插拔机制

    就是事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,其实是一种“后期绑定”,即事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

    sever端调用FtpClient

    2.动态导入模块(基于反射当前模块成员)

    import sys #固定格式
    
    def s1():
    
        print("s1")
    
    def s2():
    
        print("s2")
    
    this_module=sys.modules[__name__]# sys.modules[__name__]固定格式
    
     
    
    print(hasattr(this_module,"s1"))
    
    print(getattr(this_module,"s2"))
    
    >> 
    
    True
    
    <function s2 at 0x015A41E0>
    

      

    导入模块的推荐使用方法

    import importlib
    
    t=importlib.import_module("time")
    
    print(t.time())
    

      

    attr系列的使用

    class Foo:
    
        def __init__(self,y):
    
            self.name=y
    
     
    
        def __setattr__(self, key, value):
    
            #为对象设置属性的时候,触发运行
    
            if not isinstance(value,str):#设置类型限制
    
                raise TypeError("must be str")
    
            self.__dict__[key]=value#添加到字典中
    
        def __delattr__(self, item):
    
            #删除属性
    
            print("delatter:%s"%item)
    
            self.__dict__.pop(item)#在字典中删除
    
        def __getattr__(self, item):
    
            #属性不存在的情况下才会触发
    
            print("getattr-->%s %s"%(item,type(item)))
    
     
    
    f=Foo("egon")
    
    f.age="18"
    
    print(f.name)#在字典中查找
    
    print(f.age)#在字典中查找
    
    print(f.__dict__)
    
    del f.name#删除字典中的name属性
    
    print(f.__dict__)
    
    f.xx
    
     
    
    >> 
    
    egon
    
    18
    
    {'name': 'egon', 'age': '18'}
    
    delatter:name
    
    {'age': '18'}
    
    getattr-->xx <class 'str'>
    

      

    二次加工(定义自己的数据类型)

    二次加工使用继承的原理

    class List(list):#继承list所有的属性
    
        def append(self,p_object):#子类定义派生的方法
    
            if not isinstance(p_object,int):#设置类型限制
    
                raise TypeError
    
            super().append(p_object)#继承父类
    
        def insert(self, index, p_object):
    
            if not isinstance(p_object,int):
    
                raise TypeError
    
            super().insert(index,p_object)
    
     
    
     
    
    l=List([1,2])
    
    print(l)
    
    l.append(5)
    
    print(l)
    
    l.insert(0,52)
    
    print(l)
    
    >> 
    
    [1, 2]
    
    [1, 2, 5]
    
    [52, 1, 2, 5]
    

      

    授权:授权是包装的一个特性,包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原产品的功能,其他的则保持原样。授权的过程中,即是所有更新的功能是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

     

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

    import time
    
    class Open:
    
        def __init__(self,filepath,m="r",encode="utf8"):
    
            self.x=open(filepath,mode=m,encoding=encode)
    
            self.filepath=filepath
    
            self.mode=m
    
            self.encoding=encode
    
        def write(self,line):
    
            print("f自己的write",line)
    
            t=time.strftime("%Y-%m-%d %X")
    
            self.x.write("%s %s"%(t,line))
    
        def __getattr__(self, item):
    
            return getattr(self.x,item)
    
    f=Open("b.txt","w")
    
     
    
    f.write("123
    ")
    
    f.write("123
    ")
    
    f.write("123
    ")
    
    f.write("123
    ")
    
    f.write("123
    ")
    
    >> 
    
    2017-04-24 18:38:34 123
    
    2017-04-24 18:38:34 123
    
    2017-04-24 18:38:34 123
    
    2017-04-24 18:38:34 123
    
    2017-04-24 18:38:34 123
    
     
    
    f=Open("b.txt","r+")
    
    res=f.read()
    
    print(res)
    
    >> 
    
    2017-04-24 18:38:34 123
    
    2017-04-24 18:38:34 123
    
    2017-04-24 18:38:34 123
    
    2017-04-24 18:38:34 123
    
    2017-04-24 18:38:34 123
    

      

    
    
    
  • 相关阅读:
    Kubernetes Jenkins动态创建Slave
    运维故障汇总
    Spinnaker调用Jenkins API 返回403错误
    linux删除文件空间不释放问题解决
    华为 路由交换之DHCP
    华为 路由交换之PPPoE
    关于==和equals的探索
    springboot&mybatis 增删改查系列(二)
    springboot&mybatis 增删改查系列(一)
    nginx简单使用(windows)
  • 原文地址:https://www.cnblogs.com/asaka/p/6758524.html
Copyright © 2011-2022 走看看