一些python书或博客将类中的__init__方法称为构造函数,而实际上这种说法是不严格的,因为创建实例的方法是__new__,实例初始化的方法是__init__。__new__方法会返回一个实例,而__init__返回None。
在了解__init__与__new__的区别时,查到了篇文章:详解Python中的__init__和__new__,有这段代码:
# -*- coding: utf-8 -*- class Person(object): """Silly Person""" def __new__(cls, name, age): print ('__new__ called.') return super().__new__(cls, name, age) # >>>>有问题的一行<<<< def __init__(self, name, age): print ('__init__ called.') self.name = name self.age = age def __str__(self): return '<Person: %s(%s)>' % (self.name, self.age) if __name__ == '__main__': piglei = Person('piglei', 24) print (piglei)
运行后发现提示错误:TypeError: object() takes no parameters
显然基类object不接受参数,因此需要将有问题的那行改为:
return super().__new__(cls)
实际上,上面的例子是没必要使用__new__方法的,仅仅是为了展示方法的调用顺序。__new__方法在继承一些不可变的类(比如int, str, tuple)时会用到,比如创建一个永远保留两位小数的float类型,则可以这样写:
# -*- coding: utf-8 -*- class RoundFloat(float): def __new__(cls, value): return super().__new__(cls, round(value, 2)) print(RoundFloat(3.14159)) #3.14