题目:Python 中__init__ 与 __new 的区别?
扩展:1.怎么理解 __new__?
2. Python 中怎么实现单例模式?
3. Python 中类的实例化是什么样的过程?
答案要点:
# __new__ 的参数是 类,一旦这个方法创建过实例对象后就会调用 __init__()
object.__new__(cls[,...])
pass
# 如果需要调用父类的 __new__
python2
super(子类名, cls).__new__(cls[,...])
python3
super().__new__(cls[,...])
# 实例方法都会以 self 开头,这个 self 其实就是当前的实例对象
# 实例对象当然是要先创建的,既然在调用 __init__ 参数就已经是 self 了,
# 说明在这之前一定是有方法去生成实例对象的
object.__init__(self[,...])
pass
# 如果需要调用父类的 __init__
python2
super(子类名, self).__init__([args...])
python3
super().__init__([args...])
class Test(object):
def __init__(self):
return "123"
t = Test() # TypeError: __init__() should return None, not 'str'
new() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation. 简单翻译: new() 主要用于允许对不可变类型,如 int, str, tuple ,来自定义如何创建他们的实例。它也可以用于在使用元类时重写,以便我们客制化类的创建
首先,我们来看下第一个作用,比如我们有一种需求,是一直要得到大写的字符串,类似新增一种数据类型,它会一直返回字符串的大写形式。我们就可以用 __new__ 来实现。示例如下:
class UpperStr(str): # 继承 str
def __new__(cls, value): # 重写 __new__ 来拦截创建实例对象的过程
# 在调用父类 __new__ 时,变成大写
return super(UpperStr, cls).__new__(cls, str.upper(value))
# 单纯用 __init__() 是无法实现的
# def __init(self, value):
# return super(UpperStr, cls).__init__(str.upper(value))
s = UpperStr("abc")
print(s) # ABC
其次第二个作用,就是我们通过使用元类来构造类时,可以通过重载元类的 __new__ 方法,修改 类定义 的行为。这个在后面专题讲 元类 时再详细介绍
class MySingleton(object):
def __new__(cls):
if not hasattr(cls, 'instance'):
cls.instance = super(MySingleton, cls).__new__(cls)
m1 = MySingleton()
m2 = MySingleton()
print(id(m1) == id(m2)) # 可以用 id() 来判断是否是同一个实例对象,但一般不常用
print(m1 is m2) # 一般用 is 来判断
愿关注我们的人都能找到
属于自己的皮球