python類中的雙下劃線方法
阿新 • • 發佈:2018-01-23
att 他還 ret sel col 只有一個 war span instance
__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 = namedef __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__方法
python類中的雙下劃線方法