python的__init__和__new__方法

我们平时都是定义类和方法都是这样的:

class People(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print('This is init')
    def func(self):
        print("This is Test Func")

if __name__ == '__main__':
    s = People('张三', 25)
    print(s.name)
    print(s.age)
    s.func()
    
# This is init
# 张三
# 25
# This is Test Func

但是在使用__init__()方法初始化之前还有一步,那就是__new__()创建实例!
那么什么是__new__()?
1.new()是在类准备将自身实例化时调用,并且至少需要传递一个参数cls,此参数在实例化时由python解释器自动提供;
2.始终是类的静态方法,即使没有被加上静态方法装饰器
3.必须要有返回值,返回实例化出来的实例;可以return父类(通过super(当前类名,cls)).__new__出来的实例,或者直接是object的__new__出来的实例

从object继承

class People(object):
    def __new__(cls, *args, **kwargs):
        print('This is __new__()')  # 这是为了追踪new的执行过程
        print(type(cls))  # 这是为了追踪new的执行过程
        return object.__new__(cls)  # 调用父类的(object)的new方法,返回一个People实例,这个实例传递给init的self参数

    def __init__(self, name, age):
        self.name = name
        self.age = age
        print('This is __init__()')

    def func(self):
        print("This is testfunc")


if __name__ == '__main__':
    s = People('Tom', 18)
    print(s.name)
    print(s.age)
    s.func()


# This is __new__()
# <class 'type'>
# This is __init__()
# Tom
# 18
# This is testfunc

从自定义的类继承

class People:
    def __new__(cls, *args, **kwargs):
        print("This is People's new")
        print(type(cls))
        return super(People,cls).__new__(cls)

    def __init__(self):
        print("This is People's init")


class Children(People):
    def __init__(self, name, age):
        self.name = name
        self.age = age
        print("This is Children's init")


if __name__ == '__main__':
    child = Children('Tom', 18)
    print(child.name)
    print(child.age)


# This is People's new
# <class 'type'>
# This is Children's init
# Tom
# 18

如果没有返回值,就不能够创建实例,那么在初始化init的时候自然会出错,这就是为什么会报错没有name属性,因为根本没创建成功

class People(object):
    def __new__(cls, *args, **kwargs):
        print('This is __new__()')  # 这是为了追踪new的执行过程
        print(type(cls))  # 这是为了追踪new的执行过程

    def __init__(self, name, age):
        self.name = name
        self.age = age
        print('This is __init__()')

    def func(self):
        print("This is testfunc")


if __name__ == '__main__':
    s = People('Tom', 18)
    print(s.name)
    print(s.age)
    s.func()

# print(s.name)
# AttributeError: 'NoneType' object has no attribute 'name'
# This is __new__()
# <class 'type'>

__new__不是一定要有的,只有继承自object的类才有,子类如果没有重新定义new,会直接追溯至object的new方法,因为object是所有新式类的基类。子类中如果新写了new,可以自由选择其他的新式类,这也是为什么我们平时没有写__new__也不会报错的原因:会直接追溯至object的new方法,因为object是所有新式类的基类!

init()方法
1.有一个参数self,该self参数就是__new__()返回的实例;

2.init()在__new()的基础上完成初始化动作,不需要返回值;

3.若__new__()没有正确返回当前类cls的实例,那__init__()将不会被调用

4.创建的每个实例都有自己的属性,方便类中的实例方法调用
5.init()至少有一个参数self,就是这个__new__()返回的实例__init__()在__new__()的基础上完成一些初始化的操作

总结:
1、创建实例的时候,先new后init
2、new定义在type元类中,必须具有返回值
3、new的作用就是创建实例,然后将创建的实例传递给init进行初始化
4、__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径,还有就是实现自定义的metaclass
5.自己在定义__new__的时候,参数要与__init__函数的参数匹配,我可以不用到这些参数,但一定要匹配。或者可以使用*arg和**args的形式:*arg可以匹配任意多个未知参数

PS:
__call__是一个特殊的魔术方法, 它可以让类的实例的行为表现的像函数一样。如果在类中实现了 __call__() 方法,那么实例对象也将成为一个可调用对象。
在类X中实现如下方法:def __call__(self, *args),接受一定数量的变量作为输入
假设x是X类的一个实例,那么调用x.__call__(1,2)等同于调用x(1,2)。这个实例本身在这里相当于一个函数

class test():
    def __call__(self, *args, **kwargs):
        print(args)
        print(kwargs)
        for k, v in kwargs.items():
            print(k, v)


if __name__ == '__main__':
    t = test()
    kwagrs = {"A": 1, "B": 2}
    t(1, 2, 3, **kwagrs)


# (1, 2, 3)
# {'A': 1, 'B': 2}
# A 1
# B 2
  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
__new__和__init__是Python中的两个特殊方法。 __new__方法在一个对象实例化时调用,返回一个新创建的实例对象。它是一个级别的方法,并且在实例化之前被调用。__new__方法通常用于控制对象的创建过程,可以自定义对象的创建方式。 __init__方法在对象实例化后调用,用于初始化对象的属性。它是一个实例级别的方法,并且在__new__方法之后被调用。__init__方法用于设置对象的初始状态,可以对属性进行赋值或执行其他初始化操作。 通常情况下,我们会在__new__方法中创建对象,并在__init__方法中对对象进行初始化。但是也可以只使用其中的一个方法,根据具体需求来决定是否需要自定义对象的创建过程或初始化操作。 下面是一个示例代码,演示了__new__和__init__方法的使用: ```python class MyClass: def __new__(cls, *args, **kwargs): instance = super().__new__(cls) # 自定义对象创建过程 # 可以在这里进行一些额外的操作 return instance def __init__(self, *args, **kwargs): # 对象初始化操作 # 可以在这里对属性进行赋值 pass # 创建对象 obj = MyClass() ``` 在这个示例中,我们重写了MyClass的__new__方法和__init__方法。在__new__方法中,我们使用了super()来调用父的__new__方法,获得一个新的实例对象。在__init__方法中,我们可以对对象进行初始化操作。最后,通过实例化MyClass来创建对象obj。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值