Loading

__call__和__new__

__call__(self,*args,**kwargs)

对象加括号obj()会触发所属类的__call__的执行。Python中一切皆对象,类加括号实例化对象时也会触发元类的__call__。

class Car:
    def __call__(self, *args, **kwargs):
        print('call执行')

bmw = Car()  # 类也是对象,加括号会触发元类的__call__方法.
bmw()  # 如果没有__call__方法,则会报错。

__new__(cls,*args,**kwargs)

类加括号实例化对象时会触发自身的__new__方法执行,__new__的返回值就是实例化出的对象,__new__才是实际的构造方法。

__new__默认就是个静态方法。

class Jtgj:
    def __new__(cls, *args, **kwargs):
        print(cls)
        print(args)
        print(kwargs)
        return 1

fj = Jtgj(1,2,3,k1='v1')
print(fj,type(fj))
<class '__main__.Jtgj'>
(1, 2, 3)
{'k1': 'v1'}
1 <class 'int'>
  • 如果(新式)类中没有重写__new__方法,即在定义新式类时没有重新定义__new__时,Python默认是调用该类的直接父类的__new__方法来构造该类的实例。
  • 如果该类的父类也没有重写__new__,那么将一直按此规矩追溯至object的__new__方法,因为object是所有新式类的基类。
  • __new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
  • __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例,return返回的实例必须是通过该类实例化的对象。
  • __init__有一个参数self,就是这个__new__返回的实例,__init____new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值。

__call__、__new__、和__init__的区别:

__call__:是对象加括号时会触发所属类的方法。

__new__:是类加括号时会触发类自身的方法。

__init区别__:在__new__执行完实例化出对象之后,为对象初始化赋值时会触发执行。

posted @ 2021-01-05 21:13  吃了好多肉  阅读(126)  评论(0编辑  收藏  举报