Python进阶10---魔术方法*
特殊属性
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。查看属性
#animal.py class Animal: x = 123 def __init__(self,name): self._name = name self.__age = 10 self.weight = 20 print('animal Module\'s names = {}'.format(dir())) #animal Module's names = ['Animal', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__'] #cat.py import animal from animal import Animal class Cat(Animal): x = 'cat' y = 'abcd' class Dog(Animal): def __dir__(self): return ['dog']#指定返回列表 print('*'*10) print('Current Module : {}'.format(dir())) print('animal Module : {}'.format(dir(animal))) print('Cat Module : {}'.format(dir(Cat))) print('object Module : {}'.format(sorted(object.__dict__))) print('object Module : {}'.format(sorted(object.__dict__.keys()))) print('*'*10) tom = Cat('tom') dog = Dog('dog') print(sorted(dir(tom))) print(sorted(tom.__dict__)) print(sorted(dir(Dog))) print(sorted(dir(dog))) #dir()的等价,近似如下,__dict__字典中几乎包括了所有属性 print(sorted(set(tom.__dict__.keys())|set(Cat.__dict__.keys())|set(object.__dict__.keys())))
魔术方法
hash
class A: def __init__(self): self.a = 'a' self.b = 'b' def __hash__(self): return 1 print(hash(A()))#1 print(A(),A())#<__main__.A object at 0x00000000028F54E0> <__main__.A object at 0x00000000028F55F8> a = A() print({A(),A()})#{<__main__.A object at 0x00000000028F55F8>, <__main__.A object at 0x0000000002993F60>} s = {a,a} print(s)#{<__main__.A object at 0x00000000028F54E0>} # set内部机制会先调用is判断是否是同一对象的引用
#如果想要实现set提出相同的key,还需要增加__eq__函数
class A: def __init__(self): self.a = 'a' self.b = 'b' def __hash__(self): return 1 def __eq__(self, other): return self.a == other.a #相当于是return True print(hash(A()))#1 print(A(),A())#<__main__.A object at 0x00000000029054E0> <__main__.A object at 0x00000000029055F8> print({A(),A()})#{<__main__.A object at 0x00000000029055F8>} s = {A(),A()} print(s)#{<__main__.A object at 0x00000000029055F8>}
查看源码后发现源码中有一句__hash__=None,也就是如果调用__hash__()相当于None(),一定报错。所有类都继承object,
而这个类是具有__hash__()方法的,如果一个类不能被hash,就是把__hash__设置成None了。
#注意 from collections import Hashable print(isinstance(list(),Hashable))#False print(isinstance(list,Hashable))#True
class Point: def __init__(self,x,y): self.x = x self.y = y def __hash__(self): return hash((self.x,self.y)) def __eq__(self, other): return self.x == other.x and self.y == other.y p1 = Point(4,5) p2 = Point(4,5) print(hash(p1))#3713084879518070856 print(hash(p2))#3713084879518070856 print(p1 is p2)#False print(p1 == p2)#True print(set((p1,p2)))#{<__main__.Point object at 0x0000000002993E48>} print(isinstance(p1,Hashable))#True
bool
class A: pass print(bool(A))#True print(bool(A()))#True class B(object): def __bool__(self): return False print(bool(B))#True print(bool(B()))#False class C: def __len__(self): return 0 print(bool(C))#True print(bool(C()))#False
可视化
class A: def __init__(self): self.a = 'a' self.b = 'b' def __repr__(self): return 'repr:{} {}'.format(self.a,self.b) def __str__(self): return 'str:{} {}'.format(self.a,self.b) print(A())#print函数使用__str__ print([A()])#[]使用__str__,但其内部使用__repr__ print(str(A()))#[]使用__str__,str()函数也使用__str__ a1 = A() a2 = A() lst = [a1,a2] print(lst)#[repr:a b, repr:a b] for i in lst: #str:a b str:a b print(i)
运算符重载

更多精彩