整理类的调用方式和构造方法

时间:2022-02-12 07:22:13

前言:简单版:类加括号执行__init__()对象加括号执行__call__(),

    全版:类是type创建的,创建类的时候type的__init__()方法自动执行,类加括号的时候执行type的__call__()方法

执行流程,

第零步 :编译一下类,将类加载到内存

  执行type的__init__()方法,类是type的对象

第一步:执行type的__call__方法

    调用创建的类的__new__方法,用于创建对象。

    调用类的__init__方法,用于对对象初始化。

第二步:调用类的对象,即调用了类的call方法

执行流程

整理类的调用方式和构造方法

整理类的调用方式和构造方法整理类的调用方式和构造方法
 1 class SingletonType(type):
 2     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
 9 
10 
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)
Code

多线程

整理类的调用方式和构造方法整理类的调用方式和构造方法
 1 import threading
 2 
 3 class SingletonType(type):
 4     _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)
Code

 单例模式三种

整理类的调用方式和构造方法整理类的调用方式和构造方法
 1 import time
 2 import threading
 3 class Singleton(object):
 4     '''
 5     约定使用Singleton.instance()获取单例
 6     '''
 7     _instance_lock = threading.Lock()
 8 
 9 
10     def __init__(self, *args, **kwargs):
11         time.sleep(1)
12 
13     @classmethod
14     def instance(cls, *args, **kwargs):
15         if not hasattr(Singleton, "_instance"):
16             with Singleton._instance_lock:
17                 if not hasattr(Singleton, "_instance"):
18                     Singleton._instance = Singleton(*args, **kwargs)
19         return Singleton._instance
20 
21 
22 class Singleton1(object):
23     '''
24     基于new实现单例
25     '''
26     _instance_lock = threading.Lock()
27 
28     def __init__(self, *args, **kwargs):
29         pass
30 
31 
32     def __new__(cls, *args, **kwargs):
33         if not hasattr(Singleton1, "_instance"):
34             with Singleton1._instance_lock:
35                 if not hasattr(Singleton1, "_instance"):
36                     Singleton1._instance = object.__new__(cls, *args, **kwargs)
37         return Singleton1._instance
38 
39 # obj1 = Singleton1()
40 # obj2 = Singleton1()
41 # print(obj1,obj2)
42 
43 
44 class SingletonType(type):
45     '''
46     基于mateclass实现单例
47     '''
48     _instance_lock = threading.Lock()
49     def __call__(cls, *args, **kwargs):
50         if not hasattr(cls, "_instance"):
51             with SingletonType._instance_lock:
52                 if not hasattr(cls, "_instance"):
53                     cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)
54         return cls._instance
55 
56 class Foo(metaclass=SingletonType):
57     def __init__(self,name):
58         self.name = name
单例

 

 

一. __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

来自于脚本之家,详细请看脚本之家