Magic Method : __new__、__init__

本文详细介绍了Python中的魔法方法`__new__`和`__init__`,它们在对象创建和初始化过程中的作用。`__new__`是先于`__init__`调用,用于创建实例对象,而`__init__`则用于对象初始化,设置实例属性。通过示例展示了如何重写这两个方法,以及它们在特殊场景下的应用,如继承内置类型并修改其行为。
摘要由CSDN通过智能技术生成


Magic Method
元类相关
其他......
__new__
__init__

众所周知,
在类方法的名字中,用两条下划线开始和结束或者说 “卡住” 方法名,这个方法就被赋予了魔法。

看一只魔法博主: __一起摸🐟__(blg,*args,**kwargs):


def __new__(cls, *args, **kwargs):

创建实例对象。

是一种静态方法重写它无需使用 @staticmethod 装饰器修饰。

# in file: builtin.py
class object:
	...
	@staticmethod # known case of __new__
	def __new__(cls, *more): # known special case of object.__new__
	    """ Create and return a new object.  See help(type) for accurate signature. """
	    pass

几个demo

  1. 当作init来用。

new方法通常会返回该类的一个实例,有固定的语句:super().__new__(cls)

class A:
    def __new__(cls, *args, **kwargs):
        instance = super().__new__(cls) # 
        instance.x = args
        instance.y = kwargs
        return instance

a = A(1,2,3, y=3,z=3)
print(a.x,a.y)

'''
输出:
(1, 2, 3) {'y': 3, 'z': 3}
'''

__new__方法, 像C++的构造函数,不同的是C++ 调用构造函数时, 实例对象已经被创建

  1. 继承int, 封装一个新类nonZero,
class nonZero(int):
    def __new__(cls,value):
        if not value:
            raise ValueError(value) # 当接收0时, 会raiseError
        return super().__new__(cls,value) # if value else None
    def __init__(self,skipped_value):
        print("__init__()")
        super().__init__()
print(type(nonZero(-12)))
print(type(nonZero(0)))

"""
输出:
Traceback (most recent call last):
  File "<input>", line 11, in <module>
  File "<input>", line 4, in __new__
ValueError: 0
__init__()
<class '__main__.nonZero'>
"""
class nonZero(int):
    def __new__(cls,value):
        # if not value:
        #     raise ValueError(value)
        return super().__new__(cls,value) if value else None
    def __init__(self,skipped_value):         #此例中会跳过此方法
        print("__init__()")
        super().__init__()
print(type(nonZero(-12)))
print(type(nonZero(0)))
""" 
输出:
__init__()
<class '__main__.nonZero'>
<class 'NoneType'>
"""

new可以返回任何class的instance,不一定需要是class本身的instance。
如果发生了这种情况,则会跳过对__init__() 方法的调用。
而在某些情况下(比如需要修改不可变类实例(Python 的某些内置类型:上面的int)的创建行为),
利用这一点会事半功倍。


def __init__(self, *args, **kwargs):

这个MagicMethod很好理解:给被实例化的对象初始化,注意不是创建实例对象。

# in file: builtin.py
class object:
	...
	def __init__(self): # known special case of object.__init__
	     """ Initialize self.  See help(type(self)) for accurate signature. """
	     pass

众所周知, __init__() 方法被自动调用 ,为创建的实例增加实例属性

给一个实例对象创建新的实例属性,
除了在 __init__() 方法自动创建,
还可以: 对象名.实例属性 = 实例属性值

这个方法没有返回值
(这是错误的说法,python的函数没有显示return默认都返回None,除了函数中抛出异常或者退出程序等导致无返回值的行为),
这个方法不能显式return
第一个参数为self(取什么名无所谓,反正是这个类的实例对象,在类实例化时由python解释器自动提供),这个方法的作用是在实例对象被创建之后进行一些属性赋值等初始化的操作。


小结:

上面两个方法组合起来,就像java oop中的构造方法——初始化对象,包括用new创建对象。

python中,一般不用关心创建对象, 只管给对象初始化——创建实例变量、赋初值等。


参考:

  1. 官方文档:class object
  2. (知乎)__new__方法和__init__方法
  3. (知乎)元类相关:__new__函数和__init__函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

adingable

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值