python内置方法(魔法方法)
内置的类方法和内置的函数之间有着千丝万缕的联系 双下方法 obj.__str__ str(obj) obj.__repr__ repr(obj) class A: def __str__(self): return 'xxxxx' def __repr__(self): return 'xxxxx' a = A() print(a) # 打印一个对象的时候,就是调用a.__str__ # %s str() 实际上都是走的__str__方法 # 如果没有自己定义__str__方法,会去调用object里面的__str__方法,返回一个对象的内存地址 l = [1,2,3,4,5] # 实例化 实例化了一个列表类的对象 print(l) # 内部重写了__str__方法,才会打印出一个列表 print(repr(a)) print(%r % a) #这两个都调用了__repr__方法
__repr__方法是__str__方法的备胎 如果在类中没找到__str__就会在本类中找__repr__,如果再没找到,就找父类类中的__str__,如果再没有再找父类__repr__,直到object类 内置的方法有很多 不一定全都在object中 例如: __len__方法 析构函数 ————》在删除一个对象之前 进行一些收尾工作 __del__ class A: def __del__(self): print('执行我了!') a = A() del a 只要变量执行删除了就会执行__del__方法 应用场景 a.f = open() #打开文件 第一 在操作系统中打开了一个文件 拿到了文件操作符存在了内存中 del a # a.f 文件操作符也消失在了内存中,但这时没有关闭文件 解决:可以在__del__方法中关闭文件 __call__ class A: def __call__(self): print('执行我了!') a = A() a() --->对象后面加上一个括号,就会调用__call__方法, 如果类中没有__call__就报错(我猜想object类中也没有__call__)
__getitem__, __setitem__, delitem__, __delattr__
class Foo: def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex 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] def __delattr__(self, item): self.__dict__.pop(item) f = Foo('egon', 38, '男') print(f['name']) # 会调用 __getitem__方法 f['hobby'] = '男' # 会调用 __setitem__方法 print(f.hobby, f['hobby']) del f['hobby'] # 会调用 __delitem__方法 print(f.__dict__) del f.hobby # 会调用 __delattr__方法, 这种删除方法是object原生支持(本质上里面就有__delattr__) __new__ # 单例模式(23种设计模式之一) class A: __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__(A) return cls.__instance egon = A('egon', 38) nezha = A('nazha', 25) # egon和nezha是同一个对象 __eq__ class A: def __init__(self, name): self.name = name def __eq__(self, other): if self.name == other.name: return True else: return False obj1 = A('egon') obj2 = A('egg') print(obj1 == obj2) # 会调用__eq__方法,如果没有__eq__方法,默认比较内存地址 __hash__ class A: def __init__(self, name, sex): self.name = name self.sex = sex def __hash__(self): return hash(self.name + self.sex) a = A('egon', '男') b = A('egon', '男') print(hash(a)) print(hash(b)) # 会调用__hash__方法, 如果没有此方法会按照内存地址去hash,得到的结果就不一样