lhxxhl 2020-05-16
class Singleton(object): def __new__(cls): # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象 if not hasattr(cls, ‘instance‘): cls.instance = super(Singleton, cls).__new__(cls) return cls.instance
class si():
class_arg=‘a‘ def __init__(self): self.obj=‘b‘ self.class_arg=‘c‘
@classmethod def a(cls): return 1 def b(self): return 2
obj0=Singletonobj1 = Singleton()obj2 = Singleton()
obj3=si()obj4=si()obj5=si
Python定义的一个类,占有一个唯一的内存地址。正常情况下,对类进行实例化的时候,每实例化一次,会生成一个新的对象(对应一个新的内存地址)因此,obj3,obj4,obj5是三个不同的地址(obj3\obj4的类型是对象,obj5的类型是类)对象会继承类的方法,但是类不能使用对象的方法,在si中,a是类的方法,b是对象的方法因此obj3\obj4可以执行a,b,obj5只能执行aobj5如果要执行b,则需要传参一个对象.obj5.b(ojb3)###################我觉得可能是因为,类调用类方法的时候,第一个入参是这个类,对象调用对象的方法的时候,第一个入参是这个对象, 对象调用类的方法时,第一个入参是对象继承的类 类调用对象的方法时,不自动具备第一个入参(对象),因此需主动传入一个对象class_arg是类的属性,obj是对象的属性,对象的class_arg属性被改写成c所以,__init__方法是对对象进行初始化而__new__是对类进行初始化,生成一个新的对象,作为__init__的self在类Singleton中,重写__new__,不再返回一个新的对象,而是返回一个类的属性,那么每次构造类Singleton的对象时,不再生成一个新的对象(新的内存地址),而是获取类的instance属性地址,因此obj1和obj2是同一个内存地址,但是跟obj0不是一个地址若将Singleton改为
def __new__(cls): # 关键在于这,每一次实例化的时候,我们都只会返回这同一个instance对象 if not hasattr(cls, ‘instance‘): cls.instance = super(Singleton, cls).__new__(cls) return cls即对类初始化后直接返回类,则 obj0/obj1/obj2是同一个内存地址(都指向定义的类)