经常在 Python 类中见到__init__
方法的实现,并且如果您使用过 Python 类,那么您一定已经写过 __init__
方法。但是你可能没有写过 __new__
方法
本文会从以下几个部分来讨论这两个方法。
__init__
和__new__
方法是什么;何时应该使用它们
两种方法的区别
1.__init__
和__new__
方法是什么
__init__
方法是一个初始化方法,用于在创建对象后初始化该对象的属性,而__new__
方法用于创建对象。
当我们在类中定义__new__
和__init__
方法时,Python 首先调用__new__
方法来创建对象,然后调用__init__
方法来初始化对象的属性。
大多数编程语言只需要构造函数同时完成创建和初始化对象的方法,而 Python 同时具有构造函数和初始化器。
2.__new__
和__init__
使用示例
直接看代码
# 定义了一个基类
class Name:
# Created a __new__ method
def __new__(cls):
print(f'Called the __new__ method.')
return super(Name, cls).__new__(cls)
# Created an __init__ method
def __init__(self):
print(f"Called the __init__ method.")
# 创建了一个对象
Name()
在上面的代码中,我们在 Name 类中定义了__new__
和__init__
方法。__new__
方法接受cls
参数,该参数用于引用类,调用时,它会打印消息'Called the new method.'
然后,__init__
方法会被调用,并将实例传递给 self参数。
然后我们使用Name()
语句调用Name类时,将得到如下的输出。
Called the __new__ method.
Called the __init__ method.
这个输出告诉我们,类在初始化时会先调用__new__
方法,然后再调用__init__
方法
3.何时使用它们
3.1 new 的用例
考虑以下示例,其中我们使用__new__
方法在实例化时自定义对象。
class Reverse ( str ):
def __new__ ( cls, sequence ):
return super ().__new__(cls,sequence[::- 1 ])
seq = Reverse( "GeekPython" )
print (seq)
上面的代码定义了继承自内置类型str
的类 Reverse,我们重写__new__
方法以在创建对象之前将 sequence 反转。
nohtyPkeeG
这一功能无法使用__init__
实现,如果我们尝试这样做,结果将是一个错误。
class Reverse ( str ):
def __init__ ( self,sequence ):
super ().__init__(sequence[::- 1 ])
seq = Reverse( "GeekPython" )
print (seq)
----------
TypeError: object .__init__() 仅接受一个参数(要初始化的实例)
3.2 __init__
的用例
__init__
方法通常用于初始化对象的属性(带或不带默认值)。
class Language :
def __init__ ( self, lang= "Python" , Year= 1991 ):
self.lang = lang
self.year = 年
def show ( self ):
print ( f'Language: {self.lang} | 创建: { self.year} .' )
language = Language()
language.show()
上面的代码定义了一个Language
类和__init__
方法,它接受lang
和year
参数,默认值为"Python"
和1991
。
当我们不带参数调用Language
类时,__init__
方法会将lang
和year
设置为其默认值。
Language: Python | Founded: 1991.
总结
Python 有构造函数和初始化方法的概念。__new__
方法是构造函数方法,而__init__
方法是初始化方法。Python 首先调用__new__
创建对象,然后调用__init__
初始化对象属性。