美文网首页随缘
Python之__init__()、__new__()、__ca

Python之__init__()、__new__()、__ca

作者: 渺茫的小怪兽 | 来源:发表于2019-12-09 16:50 被阅读0次
    本篇用来介绍Python面向对象的思想,以及里边三个核心的方法。

    1. __init__()__new__()

    示例代码
    #  实际上python3里已经可以不用显示地写出继承自Object类了,这里写上python3也不会报错
    class A(object):
        def __init__(self):
            print('__init__ function')
            super(A, self).__init__()
    
        def __new__(cls):
            print('__new__ function')
            self = super(A, cls).__new__(cls)
            return self
    
    
    if __name__ == '__main__':
        a = A()
    
    输出
    __new__ function
    __init__ function
    

    从输出结果来看, __new__()先被调用,返回一个实例对象,接着__init__() 被调用。

    重点来了:实际上这里边的具体过程是,__new__ ()的返回值就是类的实例对象,这个实例对象会传递给 __init__() 中定义的 self 参数,以便实例对象可以被正确地初始化。

    2. __call__()方法

    可调用对象包括自定义的函数、内置函数和类。可以通过一个在可调用对象后边加一个()来对其进行调用。可以用callable()判断是否是可调用对象。基于上边那个代码块
    a = A()
    print(callable(A))
    print(callable(a))
    
    输出
    __new__ function
    __init__ function
    True
    False
    
    这里之所以实例对象不是可调用对象,是因为类中没有实现__call__()方法。如果在类中实现了 __call__() 方法,那么实例对象也将是一个可调用对象。
    同样的代码,加入__call__()方法
    class A(object):
        def __init__(self):
            print('__init__ function')
            super(A, self).__init__()
    
        def __new__(cls):
            print('__new__ function')
            self = super(A, cls).__new__(cls)
            return self
       
        # 这里可以传参,作为可调用对象的参数
        def __call__(self, name):
            print('__call__ function name is %s'%name)
    
    
    if __name__ == '__main__':
        a = A()
        print(callable(A))
        print(callable(a))
        a('abc')
    
    输出
    __new__ function
    __init__ function
    True
    True
    __call__ function name is abc
    
    输出说明三个函数的调用顺序是:
    __new__()__init__()__call__()
    并且,加入__call__()后实例化对象也成为了可调用对象,并且可以通过传参来调用

    接下来列举一些关于__call__()的一些例子,代码都是来自于stackoverflow,有了前边的储备,例子很简单,不做解释

    class Factorial:
        def __init__(self):
            self.cache = {}
        def __call__(self, n):
            if n not in self.cache:
                if n == 0:
                    self.cache[n] = 1
                else:
                    self.cache[n] = n * self.__call__(n-1)
            return self.cache[n]
    
    if __name__ == '__main__':
        fact = Factorial()
        for i in range(10):
            print("{}! = {}".format(i, fact(i)))
    
    输出
    0! = 1
    1! = 1
    2! = 2
    3! = 6
    4! = 24
    5! = 120
    6! = 720
    7! = 5040
    8! = 40320
    9! = 362880
    
    利用装饰器的思想,计算函数被调用了多少次
    class Counter:
        def __init__(self, func):
            self.func = func
            self.count = 0
    
        def __call__(self, *args, **kwargs):
            self.count += 1
            return self.func(*args, **kwargs)
    
    @Counter
    def foo():
        pass
    
    
    if __name__ == '__main__':
        for i in range(10):
            foo()
        print(foo.count)
    
    输出
    10
    

    相关文章

      网友评论

        本文标题:Python之__init__()、__new__()、__ca

        本文链接:https://www.haomeiwen.com/subject/mfabgctx.html