幾個反射相關的函數可參考python基礎(10)-匿名函數&內置函數中2.2.4反射相關html
重寫__str__()函數相似重寫java中的toString()函數.當沒有重寫__str__()但重寫了__repr__()函數時,__repr__()函數會充當一個__str__函數的替代函數執行java
1 class Person1: 2 def __init__(self, name, age): 3 self.name = name 4 self.age = age 5 6 def __str__(self): 7 return "name:{} age:{}".format(self.name, self.age) 8 9 10 p1 = Person1('張三', 18) 11 print(p1) # name:張三 age:18 12 13 14 class Person2: 15 def __init__(self, name, age): 16 self.name = name 17 self.age = age 18 19 def __repr__(self): 20 return "name:{} age:{}".format(self.name, self.age) 21 22 p2 = Person2('張三', 18) 23 print(p1) # name:張三 age:18
銷燬一個對象的時候執行,相似java中的析構函數python
1 class A: 2 def __del__(self): 3 print("from del") 4 5 a = A() 6 del a # from del
以'[]'的形式訪問屬性dom
1 class Person: 2 def __init__(self, name, age): 3 self.name = name 4 self.age = age 5 6 def __getitem__(self, item): 7 print("from __getitem__:{}".format(item)) 8 return self.__dict__[item] 9 10 def __setitem__(self, key, value): 11 print("from __setitem__:{} = {}".format(key, value)) 12 self.__dict__[key] = value 13 14 def __delitem__(self, key): 15 print("from __delitem__:{}".format(key)) 16 17 18 p = Person('張三', 18) 19 name = p['name'] # from __getitem__:name 20 print(name) # 張三 21 print(p.age) # 18 22 p['age'] = 20 # from __setitem__:age = 20 23 print(p.age) # 20 24 # 和@property.deleter類似 del時只是觸發對應方法 並非真的刪除 25 del p['age'] # from __delitem__:age 26 print(p.age) # 20
建立對象(self),相似java中的構造函數,在__init__()函數以前執行ide
1 class Person: 2 def __init__(self, name, age): 3 print('from __init__()') 4 self.name = name 5 self.age = age 6 7 def __new__(cls, *args, **kwargs): 8 print('from __new__()') 9 return object.__new__(cls) 10 11 p = Person('張三', 18) 12 13 # result: 14 # from __new__() 15 # from __init__()
讓一個類的實例成爲一個callable對象函數
1 class Person: 2 def __init__(self, name, age): 3 self.name = name 4 self.age = age 5 6 def __call__(self, *args, **kwargs): 7 print('name:{} age:{}'.format(self.name, self.age)) 8 9 p = Person('張三', 18) 10 print(callable(p)) # True 11 p() # name:張三 age:18
對len()函數傳入一個對象實際上就是調用這個對象的__len__()函數ui
1 class Person: 2 def __init__(self, name, age): 3 self.name = name 4 self.age = age 5 6 def __len__(self): 7 return len(self.name) 8 9 10 print(len(Person('張三', 18))) # 2
對hash()函數傳入一個對象實際上就是調用這個對象的__hash__()函數spa
1 class Person: 2 def __init__(self, no, name, age): 3 self.no = no 4 self.name = name 5 self.age = age 6 7 def __hash__(self): 8 return self.no 9 10 11 p = Person(1, '張三', 18) 12 print(hash(p)) # 1
使用'=='判斷兩個對象是否相等時,依據__eq__()函數返回的值.相似java中的equals()函數3d
1 class Person: 2 def __init__(self, name, age): 3 self.name = name 4 self.age = age 5 6 def __eq__(self, other): 7 return self.name == other.name 8 9 10 p1 = Person('張三', 19) 11 p2 = Person('張三', 18) 12 print(p1 == p2) # True
1 class Single: 2 instance = None 3 4 def __new__(cls, *args, **kwargs): 5 if cls.instance: 6 return cls.instance 7 cls.instance = object.__new__(cls) 8 return cls.instance 9 10 o1 = Single() 11 o2 = Single() 12 print(o1) # <__main__.Single object at 0x00000000021EDAC8> 13 print(o2) # <__main__.Single object at 0x00000000021EDAC8>
1 from collections import namedtuple 2 from random import choice, shuffle 3 4 CardTuple = namedtuple('Card', ['suit', 'rank']) 5 6 7 class Card: 8 def __init__(self): 9 suit_list = ['紅桃', '黑桃', '梅花', '方塊'] 10 rank_list = [str(i) for i in range(2, 11)] + ['J', 'Q', 'K', 'A'] 11 self.card_list = [CardTuple(suit, rank) for rank in rank_list for suit in suit_list] 12 13 def __str__(self): 14 return str(self.card_list) 15 16 def __len__(self): 17 return len(self.card_list) 18 19 def __getitem__(self, item): 20 return self.card_list[item] 21 22 def __setitem__(self, key, value): 23 self.card_list[key] = value 24 25 26 # 一幅撲克牌 27 card = Card() 28 print( 29 card) # [Card(suit='紅桃', rank='2'), Card(suit='黑桃', rank='2'), Card(suit='梅花', rank='2'), Card(suit='方塊', rank='2'), Card(suit='紅桃', rank='3'), Card(suit='黑桃', rank='3'), Card(suit='梅花', rank='3'), Card(suit='方塊', rank='3'), Card(suit='紅桃', rank='4'), Card(suit='黑桃', rank='4'), Card(suit='梅花', rank='4'), Card(suit='方塊', rank='4'), Card(suit='紅桃', rank='5'), Card(suit='黑桃', rank='5'), Card(suit='梅花', rank='5'), Card(suit='方塊', rank='5'), Card(suit='紅桃', rank='6'), Card(suit='黑桃', rank='6'), Card(suit='梅花', rank='6'), Card(suit='方塊', rank='6'), Card(suit='紅桃', rank='7'), Card(suit='黑桃', rank='7'), Card(suit='梅花', rank='7'), Card(suit='方塊', rank='7'), Card(suit='紅桃', rank='8'), Card(suit='黑桃', rank='8'), Card(suit='梅花', rank='8'), Card(suit='方塊', rank='8'), Card(suit='紅桃', rank='9'), Card(suit='黑桃', rank='9'), Card(suit='梅花', rank='9'), Card(suit='方塊', rank='9'), Card(suit='紅桃', rank='10'), Card(suit='黑桃', rank='10'), Card(suit='梅花', rank='10'), Card(suit='方塊', rank='10'), Card(suit='紅桃', rank='J'), Card(suit='黑桃', rank='J'), Card(suit='梅花', rank='J'), Card(suit='方塊', rank='J'), Card(suit='紅桃', rank='Q'), Card(suit='黑桃', rank='Q'), Card(suit='梅花', rank='Q'), Card(suit='方塊', rank='Q'), Card(suit='紅桃', rank='K'), Card(suit='黑桃', rank='K'), Card(suit='梅花', rank='K'), Card(suit='方塊', rank='K'), Card(suit='紅桃', rank='A'), Card(suit='黑桃', rank='A'), Card(suit='梅花', rank='A'), Card(suit='方塊', rank='A')] 30 # 撲克牌張數 31 print(len(card)) # 52 32 # 取第十張 33 print(card[10 - 1]) # Card(suit='黑桃', rank='4') 34 # 隨機抽取一張 35 print(choice(card)) # Card(suit='方塊', rank='7') 36 # 洗牌 37 shuffle(card) 38 print( 39 card) # [Card(suit='黑桃', rank='8'), Card(suit='梅花', rank='6'), Card(suit='黑桃', rank='2'), Card(suit='紅桃', rank='4'), Card(suit='梅花', rank='4'), Card(suit='紅桃', rank='K'), Card(suit='方塊', rank='9'), Card(suit='梅花', rank='7'), Card(suit='梅花', rank='9'), Card(suit='方塊', rank='4'), Card(suit='紅桃', rank='7'), Card(suit='黑桃', rank='J'), Card(suit='紅桃', rank='8'), Card(suit='梅花', rank='K'), Card(suit='紅桃', rank='J'), Card(suit='黑桃', rank='6'), Card(suit='紅桃', rank='A'), Card(suit='紅桃', rank='10'), Card(suit='梅花', rank='5'), Card(suit='方塊', rank='6'), Card(suit='方塊', rank='10'), Card(suit='方塊', rank='8'), Card(suit='方塊', rank='7'), Card(suit='黑桃', rank='Q'), Card(suit='方塊', rank='A'), Card(suit='紅桃', rank='6'), Card(suit='梅花', rank='8'), Card(suit='梅花', rank='J'), Card(suit='梅花', rank='3'), Card(suit='方塊', rank='J'), Card(suit='方塊', rank='5'), Card(suit='梅花', rank='2'), Card(suit='黑桃', rank='4'), Card(suit='梅花', rank='A'), Card(suit='黑桃', rank='3'), Card(suit='黑桃', rank='5'), Card(suit='方塊', rank='K'), Card(suit='紅桃', rank='Q'), Card(suit='方塊', rank='3'), Card(suit='方塊', rank='2'), Card(suit='黑桃', rank='A'), Card(suit='黑桃', rank='7'), Card(suit='方塊', rank='Q'), Card(suit='黑桃', rank='9'), Card(suit='紅桃', rank='2'), Card(suit='紅桃', rank='9'), Card(suit='黑桃', rank='10'), Card(suit='梅花', rank='10'), Card(suit='紅桃', rank='3'), Card(suit='紅桃', rank='5'), Card(suit='黑桃', rank='K'), Card(suit='梅花', rank='Q')]
1 class Person: 2 def __init__(self, name, age): 3 self.name = name 4 self.age = age 5 6 7 p1 = Person('張三', 18) 8 p2 = Person('張三', 18) 9 print(set([p1, p2])) # {<__main__.Person object at 0x000000000273DBA8>, <__main__.Person object at 0x000000000273DAC8>} 10 11 12 class Person: 13 def __init__(self, name, age): 14 self.name = name 15 self.age = age 16 17 def __eq__(self, other): 18 return self.name == other.name and self.age == other.age 19 20 def __hash__(self): 21 return hash(self.name + str(self.age)) 22 23 24 p1 = Person('張三', 18) 25 p2 = Person('張三', 18) 26 print(set([p1, p2])) # {<__main__.Person object at 0x0000000002702860>}
結論:使用set()給對象的去重是同時依賴對象的__hash__()和__eq__()函數的code