老师博客:http://www.cnblogs.com/Eva-J/articles/7351812.html
__new__
__init__是一种初始化的方法
__new__是构建方法,创建一个对象
class A: def __init__(self): self.x = 1 print('in init function') def __new__(cls, *args, **kwargs): print('in new function') return object.__new__(cls) a = A() print(a.x)
#return object.__new__(cls)中的cls与A等价
先执行了__new__,创建了一个空的的列表给init ,再执行了__init__方法
单例模式
一个类 始终 只有 一个 实例
当你第一次实例化这个类的时候 就创建一个实例化的对象
当你之后再来实例化的时候 就用之前创建的对象
class Singleton: def __new__(cls, *args, **kw): if not hasattr(cls, '_instance'):#Meta(元类)为空 print('执行了if') cls._instance = object.__new__(Singleton, *args, **kw) #object.__new__(Singleton, *args, **kw)表示返回一个新的空的对象 #cls._instance 可以理解为一个记录创建新对象的一个地址,每创建一个新的 #对象时,_instance便是其地址,并且在创建新的对象前,一直指向上个地址 else:#元类不为空,没有给一个新的地址 print('执行了else') print(cls._instance) return cls._instance one = Singleton() two = Singleton() two.a = 3 print(one.a) # 3 # one和two完全相同,可以用id(), ==, is检测 print(id(one)) # 29097904 print(id(two)) # 29097904 print(one == two) # True print(one is two) #True
__eq__
class A: def __init__(self,name): self.name=name def __eq__(self,other): print('执行了__eq__') if self.name == other.name: return True else: return False a = A('a') b=A('a') print(a==b)#True
print(a=='b')
#报错 AttributeError: 'str' object has no attribute 'name'
print('a'== a)
#报错 AttributeError: 'str' object has no attribute 'name'
__eq__是同类的对象比较,一般默认的是比较内存地址,而自己定义这个方法可以比较其他的属性是否一致,例如上面的比较对象的属性
注意,不同的类的对象之间比较会报错,见上面
__hash__
__hash__是表示hash()的方法,一般来说类的哈希见Object.__hash__,但是自己可以定义自己类的哈希的方法,但是注意,list,tuple,set是不可哈希的,除非自己定义,改写hash的方法
class A: def __init__(self,name,age): self.name=name self.age=age def __hash__(self): return hash(str(self.name)+str(self.age)) a=A('alex',22) print(hash(a)) print(hash({1:2}))#报错