__getitem__,__setitem__和__delitem__
实现了对象属性的字典化操作。
class Person: def __init__(self, name, age, hobby): self.name = name self.age = age self.hobby = hobby def __getitem__(self, item): if hasattr(self, item): return self.__dict__[item] def __setitem__(self, key, value): self.__dict__[key] = value def __delitem__(self, key): del self.__dict__[key] zxc = Person(‘zxc‘, 26, ‘read‘) print(zxc.name) # zxc 对象原生查看属性的方法 print(zxc[‘name‘]) # zxc 通过getitem实现的查看方法 zxc[‘name‘] = ‘zzy‘ # 通过setitem实现修改 zxc[‘weight‘] = 70 # 通过setitem实现增加 print(zxc.__dict__) # {‘weight‘: 70, ‘name‘: ‘zzy‘, ‘hobby‘: ‘read‘, ‘age‘: 26} del zxc[‘hobby‘] # 通过delitem实现删除 print(zxc.__dict__) # {‘name‘: ‘zzy‘, ‘weight‘: 70, ‘age‘: 26}
__new__:构造方法:创建一个对象
实例化要用到__new__方法
class Foo: def __init__(self, name): self.name = name def __new__(cls, *args, **kwargs): return ‘创建一个对象‘ obj = Foo(‘zxc‘) # 当实例化一个对象的时候,调用的就是__new__方法。 print(obj) # 打印:创建一个对象
class Foo: def __init__(self, name): self.name = name def __new__(cls, *args, **kwargs): return object.__new__(Foo) # object里面的__new__方法用来构造对象 obj = Foo(‘zxc‘) print(obj) # <__main__.Foo object at 0x000002CADD5C0048>
__new__方法的使用:单例模式
一种程序设计模式:一个类始终只有一个实例
class Foo: __instance = False def __init__(self, name, age): self.name = name self.age = age def __new__(cls, *args, **kwargs): if cls.__instance: # 当实例化一个对象之后,后面的实例化就使用之前的对象 return cls.__instance cls.__instance = object.__new__(cls) return cls.__instance a = Foo(‘zxc‘, 25) b = Foo(‘zxf‘, 22) print(a.__dict__) # {‘name‘: ‘zxf‘, ‘age‘: 22} print(b.__dict__) # {‘name‘: ‘zxf‘, ‘age‘: 22} b.hobby = ‘read‘ print(a.hobby) # read # a和b是同一个对象
__eq__和__hash__
class Foo: def __init__(self, name): self.name = name a = Foo(‘zxc‘) b = Foo(‘zxc‘) print(a == b) # False 正常一个类的两个对象即使属性一样他还是不同的 class Foo: def __init__(self, name): self.name = name def __eq__(self, other): if self.name == other.name: return True else: return False a = Foo(‘zxc‘) b = Foo(‘zxc‘) print(a) # <__main__.Foo object at 0x000001543BA60048> print(b) # <__main__.Foo object at 0x000001543BA604E0> print(a == b) # True a和b并不相同,但结果却是True,说明==比较时调用的就是__eq__方法,默认使用的都是object的__eq__方法
class Foo: def __hash__(self): return 10 a = Foo() print(hash(a)) # 10 内置函数hash调用的就是对象的__hash__方法
set会依赖__eq__和__hash__
class Foo: def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def __hash__(self): return hash(self.name+self.sex) def __eq__(self, other): if self.name == other.name and self.sex == other.sex: return True else: return False a = Foo(‘zxc‘, 25, ‘男‘) b = Foo(‘zxc‘, 24, ‘男‘) print(set([a, b])) # {<__main__.Foo object at 0x000002BFB7FC04E0>} # 当name和sex相同时,a和b被认为是同一个,set后去重 # 注释掉类里的__hash__方法 print(set([a, b])) # 报错 显示类Foo不能哈希 说明set依赖对象的__hash__方法 # 注释掉类里的__eq__方法 print(set([a, b])) # 结果还是两个元素 并没有去重 说明set的去重还依赖对象的__eq__方法返回结果
__len__
class Foo: def __len__(self): return 10 a = Foo() print(len(a)) # 10 内置函数len调用的就是对象的__len__方法,默认使用的都是object的__len__方法