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