1. 程式人生 > >python類中的雙下劃線方法

python類中的雙下劃線方法

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 = 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__方法

python類中的雙下劃線方法