• 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__方法
  • 相关阅读:
    HDU-2602-Bone Collector
    HDU-1171-Big Event in HDU
    javascript概要
    核桃的数量
    P3372 【模板】线段树 1
    P3373 【模板】线段树 2
    拿糖果
    第二点五个不高兴的小明
    树的直径
    1240. 完全二叉树的权值
  • 原文地址:https://www.cnblogs.com/zxc-Weblog/p/8336925.html
Copyright © 2020-2023  润新知