众所周知,
在类方法的名字中,用两条下划线, 开始和结束或者说 “卡住” 方法名,这个方法就被赋予了魔法。
看一只魔法博主: __一起摸🐟__(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
- 当作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++ 调用构造函数时, 实例对象已经被创建。
- 继承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中,一般不用关心创建对象, 只管给对象初始化——创建实例变量、赋初值等。
参考: