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


    前言:简单版:类加括号执行__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

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

  • 相关阅读:
    SQLite存储类(数据类型)
    SQLite常用命令
    C# 跨线程操作无效
    Android打开新的Activity并同时关闭当前Activity
    SQLite实现Top功能
    Android调用Sqlite数据库时自动生成db-journal文件的原因
    C#使用SqlDataReader读取数据库数据时CommandBehavior.CloseConnection参数的作用
    Android计算时间差
    PS通道抠图总结
    Android再次激活Activity时触发事件用于列表重新读取载入
  • 原文地址:https://www.cnblogs.com/xiesibo/p/8258941.html
Copyright © 2020-2023  润新知