zoukankan      html  css  js  c++  java
  • python之路(9)反射、包装类、动态模块导入

    目录


    反射

     python提供自省的四个方法:

    hasattr(object,name)  判断object中有没有有个name字符串对应对应的方法和属性

    class demo:
        name = 'chen'
        age = '22'
        def test_func(self):
            print("存在")
    
    
    hasattr(demo, 'test_func') #True
    hasattr(demo, 'name') #True
    hasattr(demo, 'date') #False 

    (常用)getattr(object,name,default=None)  根据name字符串寻找object中对应的数据属性或函数属性,相当于object.name

    class demo:
        name = 'chen'
        age = '22'
        def test_func(self):
            print("存在")
    
    
    getattr(demo, 'test_func') #<function demo.test_func at 0x00000264F0ABA9D8>
    getattr(demo, 'name') #chen
    getattr(demo, 'date') #报错

    setattr(object,name,value)   根据name字符串去设置或修改object中相对应的数据属性或函数属性,相当于object.name=value

    class demo:
        name = 'chen'
        age = '22'
        def test_func(self):
            print("存在")
    
    #设置数据属性
    setattr(demo,'date','2018/11/21')
    print(getattr(demo, 'date')) #2018/11/21
    #设置函数属性
    setattr(demo,'test2_func',lambda  x:x+2)
    print(getattr(demo, 'test2_func')(8)) #10

    delattr(object,name)  根据name字符串去删除object中相对应的数据属性或函数属性,相当于del object.name

    class demo:
        name = 'chen'
        age = '22'
        def test_func(self):
            print("存在")
    
    
    delattr(demo,'name') 

     反射使用类中用到的三个内置函数

    (常用)_getattr_  当访问的属性找不要的时候执行这个这个函数

    class demo:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def __getattr__(self, item):
            print("不存在%s属性"%item)
    
    
    d1 = demo('chen',22)
    #调用不存在的属性
    d1.data #不存在data属性

    补充:

      _getattribute_    当访问属性时,无论属性存不存在,都会执行,当与_getattr_函数同时存在时,优先执行_getattribute_ ,忽略_getattr_函数。

              所以_getattr_是在_getattribute_ 中抛出一个AttributrError时才会执行

    class demo:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def __getattr__(self, item): #会被忽略
            print("这里是getattr")
    
        def __getattribute__(self, item):
            print("这里是getattribute")
            # raise AttributeError('抛出异常')
    
    d1 = demo('chen',22)
    #调用不存在的属性
    d1.data #这里是getattribute
    
    
    class demo:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    
        def __getattr__(self, item):
            print("这里是getattr")
    
        def __getattribute__(self, item):
            print("这里是getattribute")
            raise AttributeError('抛出异常') #抛出异常,会调用__getattr__方法去执行
    
    d1 = demo('chen',22)
    #调用不存在的属性
    d1.data #这里是getattribute
    这里是getattr

    _setattr_   当赋值属性值时执行这个函数

    class demo:
        def __init__(self,name,age):
            self.name = name #赋值操作
            self.age = age #赋值操作
    
        def __setattr__(self, key, value):
            print("key:%s value:%s"%(key,value))
            self.__dict__[key]=value
    
    d1 = demo('chen',22) #key:name value:chen  key:age value:22

    _delattr_   当删除属性事执行这个函数

    class demo:
        def __init__(self,name,age):
            self.name = name #赋值操作
            self.age = age #赋值操作
    
        def __delattr__(self, item):
            print("删除%s"%item)
            self.__dict__.pop(item)
    
    
    d1 = demo('chen',22)
    del d1.name #删除name

    变量赋值操作的自定制之所有字符串大写

    class demo:
        def __init__(self,name,age):
            self.name = name #赋值操作
            self.age = age #赋值操作
    
        def __setattr__(self, key, value):
            if type(value) is str:
                self.__dict__[key] = value.upper() #制定大写
            else:
                self.__dict__[key] = value
    
    d1 = demo('chen',22)
    print(d1.__dict__) #{'name': 'CHEN', 'age': 22}
    

     利用继承二次包装标准类

    class List(list):
        def append(self, value):
            if type(value) is str:
                super().append(value)
            else:
                print('只能添加字符串类型')
    
        def show_midlle(self):  #求列表中间的value
            mid_index=int(len(self)/2)
            return self[mid_index]
    
    l1=List('chen')
    l1.append(12)  #只能添加字符串类型
    l1.show_midlle() #e
    

     利用授权二次包装标准类

     授权也是一种包装,但不是通过继承去实现,利用_getattr_实现

    import time
    class FileHandle:
        def __init__(self,filename,mode='r',encoding='utf-8'):
            #已实现的功能,依然用原来的功能
            self.file=open(filename,mode,encoding=encoding)
    
        # 定制在写入文件时,写入时间的写函数
        def write(self,line):
            t=time.strftime('%Y-%m-%d %X')
            self.file.write('%s %s' %(t,line))
    
        #如果访问的属性不纯在
        def __getattr__(self, item):
    
            return getattr(self.file,item)
    
    f1=FileHandle('a.txt','w+',encoding='utf-8')
    
    f1.write('第一条
    ')
    f1.write('第二条
    ')
    f1.write('第三条
    ')
    
    2018-11-21 19:11:07 第一条
    2018-11-21 19:11:07 第二条
    2018-11-21 19:11:07 第三条

    动态导入模块 

    # 导入的是m1,不是m1下的t文件
    # 这样导入的是路径最顶层的模块
    module_t = __import__('m1.t') #
    print(module_t) #<module 'm1' (namespace)>
    module_t.t.test3()  #这里是t模块
    
    
    #利用模块导入
    import  importlib
    #导入的是m1下的t文件
    m = importlib.import_module("m1.t")
    print(m) # <module 'm1.t' from 'F:\PyCharm 2018.2.3\PycharmProjects\chen\day13\m1\t.py'>
    m.test3() #这里是t模块
    
  • 相关阅读:
    (转)sql server 生成树形菜单
    在Sublime Text 3中配置Python3的开发环境/Build System
    按回车键提交表单 问题
    多页面 返回 到同一页面
    sql 查找出表里所有字段
    sql 创建表变量,临时表
    sql语句中数据类型转换函数:CAST 和 Convert
    sql isnull函数
    判断值是否为整数
    TSQL游标使用
  • 原文地址:https://www.cnblogs.com/shuzhixia/p/9995380.html
Copyright © 2011-2022 走看看