3月16日学习内容整理:metaclass
1、首先我們要知道:
對象是由類創建的,而類是由type類創建的
所以創建類有兩個方法:
class Foo(object):pass# 類名,繼承關系,屬性 Foo = type('Foo',(object,),{})上面第一種方法也是默認用type來創建類的,我們就可以理解為類其實就是type的一個對象
當類名()這樣加括號的時候,會首先調用type的_ _call_ _方法,在這個方法里會調用類的_ _new_ _方法來創建一個裸著的對象,也就是開辟內存空間,但是沒有任何東西,繼而繼續調用執行類的_ _init_ _方法來給對象封裝一些屬性
補充一下:對象()這樣加括號就會調用類的_ _call_ _方法
?
2、metaclass就可以指定我們自定義的type類,當用類名()時就會從我們定義的metaclass參數值的類中調用_ _call_ _方法,要依次調用_ _new_ _和_ _init_ _方法,返回對象
這樣做的一個好處是我們在實例對象時先是_ _new_ _方法再是_ _init_ _方法,用了我們自定義type類的時候我們就可以在new方法和init方法之間就可以做一些操作了
class MyType(type):def __init__(self,*args,**kwargs):super(MyType,self).__init__(*args,**kwargs)def __call__(self, *args, **kwargs):obj = self.__new__(self,*args, **kwargs) # object.__init__(....)obj.__init__(*args, **kwargs)# self.__init__(obj,*args, **kwargs)return objclass Foo(object,metaclass=MyType):def __init__(self):print('xxx')# 1. 類是MyType的對象。由MyType(...) # 2. Foo() obj = Foo() print(obj)?
注意在python2中metaclass的寫法不同:
# python3 class Foo(object,metaclass=MyType):pass # python2 class Foo(object):__metaclass__ = MyType?
?
補充:
metaclass的作用:就是用來指定當前類由誰創建,對派生類也是一樣的,也就是當父類指定了metaclass以后,它的派生類也得由metaclass指定的類來創建
?
第二種指定metaclass類的方法
class MyType(type):def __init__(self, *args, **kwargs):super(MyType, self).__init__(*args, **kwargs)def __call__(cls, *args, **kwargs):print('xxxx')return super(MyType, cls).__call__(*args, **kwargs)# Foo繼承的類是由MyType創建的,所以Foo類繼承這個創建出來的類,那Foo的metaclass也是MyType class Foo(MyType('Base', (object,), {})):pass obj = Foo()?
第三種指定metaclass類的方法
class MyType(type):def __init__(self, *args, **kwargs):super(MyType, self).__init__(*args, **kwargs)def __call__(cls, *args, **kwargs):return super(MyType, cls).__call__(*args, **kwargs)def with_metaclass(base):return MyType('XX', (base,), {})# Foo繼承的是with_metaclass函數的返回值,返回值仍是由MyType創建的一個類 # 所以Foo作為創建出來的類的派生類,Foo的metaclass也是MyType class Foo(with_metaclass(object)):pass?
?
總結:類和對象加括號時的流程
類是type創建的,所以說類就是type的一個對象,而type又是由object創建的
我們創建類的時候實際上就是寫type(),那這樣的話就會調用object的__call__方法,在這個方法中會調用type的__new__和__init___方法
我們實例類對象時就是寫類(),那這樣的話就會調用type的__call__方法,在這個方法中會調用類的__new__和__init__方法
轉載于:https://www.cnblogs.com/wanghl1011/articles/8584186.html
總結
以上是生活随笔為你收集整理的3月16日学习内容整理:metaclass的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Golang入门教程(十五)指针
- 下一篇: 视频编码与封装