python類中的雙下划線方法


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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM