整理類的調用方式和構造方法
阿新 • • 發佈:2018-02-15
-c .com per reading 實現 super 變量 image next
前言:簡單版:類加括號執行__init__()對象加括號執行__call__(),
全版:類是type創建的,創建類的時候type的__init__()方法自動執行,類加括號的時候執行type的__call__()方法
執行流程,
第零步 :編譯一下類,將類加載到內存
執行type的__init__()方法,類是type的對象
第一步:執行type的__call__方法
調用創建的類的__new__方法,用於創建對象。
調用類的__init__方法,用於對對象初始化。
第二步:調用類的對象,即調用了類的call方法
執行流程
1 class SingletonType(type):Code2 def __init__(self, *args, **kwargs): 3 super(SingletonType, self).__init__(*args, **kwargs) 4 5 def __call__(cls, *args, **kwargs): 6 obj = cls.__new__(cls, *args, **kwargs) 7 cls.__init__(obj, *args, **kwargs) # Foo.__init__(obj) 8 return obj 910 11 class Foo(metaclass=SingletonType): 12 def __init__(self, name): 13 self.name = name 14 15 def __new__(cls, *args, **kwargs): 16 return object.__new__(cls) 17 18 19 obj = Foo(‘name‘) 20 print(obj)
多線程
1 import threading 2 3 class SingletonType(type):Code4 _instance_lock = threading.Lock() 5 def __call__(cls, *args, **kwargs): 6 if not hasattr(cls, "_instance"): 7 with SingletonType._instance_lock: 8 if not hasattr(cls, "_instance"): 9 cls._instance = super(SingletonType,cls).__call__(*args, **kwargs) 10 return cls._instance 11 12 class Foo(metaclass=SingletonType): 13 def __init__(self,name): 14 self.name = name 15 16 17 obj1 = Foo(‘name‘) 18 obj2 = Foo(‘name‘) 19 print(obj1,obj2)
一. __init__()
__init__()是對象的構造方法
1 class Minal: 2 pass 3 4 print(type(Minal)) 5 print(Minal.__class__) 6 print(Minal.__class__.__bases__) 7 8 9 <class ‘type‘> 10 <class ‘type‘> 11 (<class ‘object‘>,)
二.__new__()
__new__(cls, *args, **kwargs)當創建對象時調用在init方法前調用,創建對象時調用,返回當前對象的一個實例;註意:這裏的第一個參數是cls即class本身
三.__call__()
__call__(self, *args, **kwargs) 如果類實現了這個方法,相當於把這個類型的對象當作函數來使用,相當於 重載了括號運算符
1 先來看看如下示例代碼: 2 #call.py 一個class被載入的情況下。 3 class Next: 4 List = [] 5 6 def __init__(self,low,high) : 7 for Num in range(low,high) : 8 self.List.append(Num ** 2) 9 10 def __call__(self,Nu): 11 return self.List[Nu] 12 13 如果 這樣使用: 14 b = Next(1,7) 15 print b.List 16 print b(2) 17 18 那麽回饋很正常: 19 [1, 4, 9, 16, 25, 36] 20 9 21 22 但如果這樣使用: 23 b = Next 24 b(1,7) 25 print b.List 26 print b(2) 27 $python ./call.py 28 [1, 4, 9, 16, 25, 36] 29 30 Traceback (most recent call last): 31 File "cal.py", line 17, in <module> 32 print b(2) 33 TypeError: __init__() takes exactly 3 arguments (2 given) 34 35 __init__是初始化函數,在生成類的實例時執行。 36 而__call__是模擬()的調用,需要在實例上應用,因此這個實例自然是已經執行過__init__了。 37 你所舉的後面那個例子: 38 b = Next 39 這並不是創建實例,而是將class賦給一個變量。因此後面使用b進行的操作都是對Next類的操作,那麽其實就是: 40 Next(1,7) 41 print Next.List 42 print Next(2) 43 希望本文所述對大家的Python程序設計有所幫助。View Code
來自於腳本之家,詳細請看腳本之家
整理類的調用方式和構造方法