创建实例的时候, 先运行的_new_方法, _new_创建对象 Student object(实例)返回给 _init_ 里面的第一个参数self
class Student(object): def __new__(cls,name): cls.m=2 print("__new__运行了") print(super().__new__(cls)) return super().__new__(cls) def __init__(self,name): self.name=name print(self) print("__init__运行了") c=Student("小明") print(c.name,c.m) ''' __new__运行了 <__main__.Student object at 0x02025530> <__main__.Student object at 0x02025530> __init__运行了 小明 2 '''
- __init__是当实例对象创建完成后被调用的,然后设置对象属性的一些初始值。
- __new__是在实例创建之前被调用的,因为它的任务就是创建实例然后返回该实例,是个静态方法。
- __new__ 至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供
- __new__ 的参数除了cls外要有和实例化类给出的参数数量一致
- __new__也可以设置对象属性(如果init重新设置了对象属性那么将被覆盖)
- self代表的是类的实例,而cls则代表的是类本身
__new__的运用场景
- 创建对象时候,同时创建一个类变量
- 允许继承不可变类型(str,int, tuple)
- 实现单例设计模式
允许继承不可变类型
用__new__来生成一个正数的类
class PositiveInteger(int): def __new__(cls,value): return super(PositiveInteger,cls).__new__(cls,abs(value)) def __init__(self,value): super(PositiveInteger,self).__init__() c = PositiveInteger(-1) print(c) #打印出1
实现单例设计模式
单例设计模式是为了解决一个类有多个对象的时候,多个对象引用同一个内存地址,以减少内存占用的问题
实现思路:
重写父类的__new__方法,使每次返回的内存地址引用都为同一个
class Singleton(object): boolean = None def __new__(cls): if cls.boolean == None: cls.boolean = super().__new__(cls) return cls.boolean c1 = Singleton() c2 = Singleton() print(c1) print(c2) ''' <__main__.Singleton object at 0x02485670> <__main__.Singleton object at 0x02485670> '''
可以看出我们创建了两个实例,并且返回的内存都是一样的,这避免了内存的重复占用