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\n这里是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('第一条\n')
f1.write('第二条\n')
f1.write('第三条\n')
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模块

 

转载于:https://www.cnblogs.com/shuzhixia/p/9995380.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值