python类中的双下划线方法

Posted 蔠缬草

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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__方法

 

以上是关于python类中的双下划线方法的主要内容,如果未能解决你的问题,请参考以下文章

python中的双下划线__是啥意思? [复制]

理解Python的双下划线命名(转)

python的单下划线和双下划线

Python中_,__,__xx__的区别

Python的双下划方法

摆脱 Flutter UI 中的双下划线