# 写一个单例类
# __名子__
# 类中的特殊方法、内置方法
# 双下方法
# 魔法方法
# __call__ flask
# __new__ 特别重要 写一个单例类
# __len__
# __str__ /__repr__
__call__
# __call__ flask class A: def __call__(self, *args, **kwargs): print("执行__call__方法") # # a = A() # a() # 对象加()执行call方法 # A()() # # # 执行__call__方法 # # 执行__call__方法 class B: def __init__(self,cls): print("在实例化A之前做一些事情") self.a = cls() self.a() print("在实例化A之后做一些事情") B(A) # 很多源码都是这样写的
__len__ 对对象执行len函数里面必须要有__len__方法
# __len__ #len() # __iter__ #iter # __next__ # next() # l = [1,2,3] # # def it(obj): # return obj.__iter__() # # print(it(l)) class Mylist(): def __init__(self): self.lst = [1,2,3,4,5,6] def __len__(self): print("执行__len__函数") return len(self.lst) # 在对对象进行操作时,可以修改,让len执行你想要的操作 l = Mylist() # print(l.lst) # print(len(l)) # TypeError: object of type 'Mylist' has no len() 对象没有长度。添加__len__ 函数 # print(len(l)) # 执行对象里面的len函数 # 当需要执行对象的len函数时,类里面必须有__len__函数 # 执行外部的len函数 ab = [1,2,3,4] print(len(ab)) # 类 # self.s = "" # len(obj) = str长度 class Test: def __init__(self,s): self.s = s def __len__(self): return len(self.s) t = Test("abafhaifhakj") print(len(t))
__new__ 单例类 (构造方法) __init__ 不是构造方法,是初始化方法
class Single: def __new__(cls, *args, **kwargs): obj = object.__new__(cls) print("在new方法里面", obj) return obj # 这里执行new方法,返回对象空间。在执行new方法时,传递cls,因为此时没有对象空间self ,所哟只能传递cls 类空间 # 正常情况下不需要执行new函数,因为继承的objecr会自动执行 def __init__(self): print("init",self) # 实例化过程中先开辟一个空间,属于对象的 # 把对象空间传递给self ,执行init # 将这个对象空间返回给调用者 obj = Single() # 在new方法里面 <__main__.Single object at 0x000001B97B41B4A8> # init <__main__.Single object at 0x000001B97B41B4A8> # 先执行Single的new方法,Single里面没有,所以执行Object里面的new方法 # new方法在实例化对象的时候,在__init__之前 # 单例类 如果一个类只能创建一个实例.只开辟一个空间,那么这个类就是单例类 class B: __ISINSTANCE = None # def __new__(cls, *args, **kwargs): # global obj # if not cls.__ISINSTANCE: # obj = object.__new__(cls) # cls.__ISINSTANCE = True # return obj # UnboundLocalError: local variable 'obj' referenced before assignment 赋值之前引用了局部变量obj def __new__(cls, *args, **kwargs): if not cls.__ISINSTANCE: cls.__ISINSTANCE = object.__new__(cls) return cls.__ISINSTANCE # UnboundLocalError: local variable 'obj' referenced before assignment 赋值之前引用了局部变量obj def __init__(self,name,age): self.name = name self.age = age b1 = B("ly",999) b2 = B("dudu",666) print(b1.name) print(b2.name)
__str__
# __str__ l = [1,2,3] # 相当于实例化一个list的对象 # # l 是一个对象 print(l) class Student: # def __str__(self): # return "{} {} {}".format(self.name,self.school,self.age) def __init__(self,name): self.name = name self.school = "good" self.age = 26 ly = Student("liuy") print(ly.name) # print(ly) print(str(ly)) # print("学生1: %s" % ly) # print一个对象相当于调用一个对象的__str__ 方法 # 实现强转时,str(obj)相当于执行__str__方法 # str(obj)相当于执行obj.__str__方法 # %obj 相当于执行obj.__str__ 方法
所有的魔术方法没有需要在外面直接调用的,通常在类里面实现这些方法,然后在外部通过对象调用时,可以影响这些方法