1. 程式人生 > >python之路(9)反射、包裝類、動態模組匯入

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屬性

_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模組