元類

元類

一、exec

exec是python內置函數,能夠將字符串的代碼添加到自定義的名稱空間中python

語法:exec(字符串形式的python代碼,全局名稱空間,局部名稱空間)函數

字符串形式的代碼是加載到自定義的名稱空間中,能夠在字符串名稱空間中使用global將一些屬性和方法引入自定義的全局名稱空間中code

名稱空間是一個字典形式的對象

# 字符串形式的代碼
code = '''

x = 10
y = 20

def func():
	pass
def __init__():
	pass
'''

# 自定義的全局名稱空間
global_dic = {'z':100}

# 自定義的局部名稱空間
local_dic = {'t':300}
print(global_dic)
print(local_dic)
exec(code,global_dic,local_dic)
print(code)
print(global_dic)
print(local_dic)  # {'t': 300, 'x': 10, 'y': 20, 'func': <function func at 0x00000123A6602558>, '__init__': <function __init__ at 0x00000123A6602B88>}

二、元類

一、什麼是元類

類的類就是type,type就是元類字符串

type是python內置的元類get

二、爲何要使用元類

元類能夠控制類的建立過程,能夠經過自定義的一個元類來控制建立的類的過程it

三、怎麼使用元類

# 自定義一個元類
class MyMetaClass(type):
    # 控制類的建立,重寫type中的__init__
    def __init__(self, class_name, class_base, class_dict):
        # 控制建立類時首字母必須大寫
        if not class_name.istitle():
            raise NameError('類的首字母必需要大寫!!')
        # 控制建立類時必需要寫註釋
        if not class_dict.get('__doc__'):
            raise TypeError('定義必需要寫註釋!!')
        # 必需要將從新定義__init__返回給type中的__init__
        super().__init__(class_name, class_base, class_dict)


# 使用自定義元類(類名,基類,類的名稱空間)來產生類
class User(object, metaclass=MyMetaClass):
    '''
    註釋必需要寫啊!
    '''
    def __init__(self):
        pass
    x = 10

# 調用類產生對象
obj = User()
print(obj)
爲何調用類就會產生一個空對象:內部執行了__ new__

爲何必定會執行__ new__:實際上是type內部調用了一次__call__,由__call__來幫你調用__new__產生新的空對象,全部元類中的__call__ 就是建立類的過程
class MyMetaClass(type):
    def __init__(self,class_name,class_base,class_dict):
        if not class_name.istitle():
            raise NameError('類定義必須首字母大寫')
        super().__init__(class_name,class_base,class_dict)
    # 模擬__call__建立類的過程
    def __call__(self,*args,**kwargs):
        # 創造一個新空對象
        obj = object.__new__(self)
        # 調用類時,__call__會立馬調用user.__init__,而且會將obj連同參數一併傳入__init__
        self.__init__(obj,*args,**kwargs)
        # 返回一個真正的對象
        return obj
相關文章
相關標籤/搜索