• python 面向对象进阶之对象内置方法


    反射相关

    常用的就是hasattr,getattr

    class A():
        def __init__(self):
            pass
        def func(self):
            print("func")
    
    a = A()
    a.name = "123"
    a.age = 123
    print(getattr(a,"name"))
    getattr(a, "func")()
    print(hasattr(a, "ame"))

     setattr,delattr,用于设置变量和删除变量,不常用

     用于对象的一些内置方法:

    __str__

    调用对象,自动输出

    class B:
    
        def __str__(self):
            return 'str : class B'
    
        def __repr__(self):
            return 'repr : class B'
    
    b = B()
    print('%s' % b)
    print('%r' % b)

    __getitem__, __setitem__, __delitem__

    用于索引操作,如字典。以上分别表示获取、设置、删除数据

    class C(object):
    def __init__(self): self.value = {} self.name = 'test' def __getitem__(self, item): print '__getitem__', item return self.value[item] def __setitem__(self, key, value): print '__setitem__', key, value self.value[key] = value def __delitem__(self, key): print '__delitem__', key del self.value[key] def __len__(self): return len(self.value) print C.__doc__ c = C() #print c #result = c['k1'] c['k2'] = 5 c['k1'] = "Hello" print c['k2'] print len(c)

    __call__

    对象后面加括号,触发执行。

    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

    class Foo:
    
        def __init__(self):
            pass
        
        def __call__(self, *args, **kwargs):
    
            print('__call__')
    
    
    obj = Foo() # 执行 __init__
    obj()       # 执行 __call__

    __hash__

    外部哈希,依赖与内置__hash__方法

    class A():
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __hash__(self):
            return hash(str(self.a)+str(self.b))
    a = A()
    print(hash(a))

    __eq__方法

    用与判断两个对象是否相等,因为 == 默认是比较内存地址

    class A():
        def __init__(self, name):
            self.name = name
    
        def __eq__(self, other):
            if (self.__dict__ == other.__dict__):
                return True
    
    a = A("test")
    b = A("test")
    print(a == b)

    set()对象去重,依赖于hash,eq方法

    class Person:
        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
    
    p_lst = []
    for i in range(84):
        p_lst.append(Person('egon',i,'male'))
    
    print(p_lst)
    print(set(p_lst))

    __del__()方法

    创建对象后,python解释器默认调用__init__()方法;

    当删除一个对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法

    import time
    class Animal(object):
        # 初始化方法
        # 创建完对象后会自动被调用
        def __init__(self, name):
            print('__init__方法被调用')
            self.__name = name
        # 析构方法
        # 当对象被删除时,会自动被调用
        def __del__(self):
            print("__del__方法被调用")
            print("%s对象马上被干掉了..."%self.__name)
    # 创建对象
    dog = Animal("哈皮狗")
    # 删除对象
    del dog
    cat = Animal("波斯猫")
    cat2 = cat
    cat3 = cat
    print("---马上 删除cat对象")
    del cat
    print("---马上 删除cat2对象")
    del cat2
    print("---马上 删除cat3对象")
    del cat3
    print("程序2秒钟后结束")
    time.sleep(2)

    结果:

    总结

    • 当有1个变量保存了对象的引用时,此对象的引用计数就会加1
    • 当使用del删除变量指向的对象时,如果对象的引用计数不会1,比如3,那么此时只会让这个引用计数减1,即变为2,当再次调用del时,变为1,如果再调用1次del,此时会真的把对象进行删除

    __slots__

    现在我们终于明白了,动态语言与静态语言的不同

    动态语言:可以在运行的过程中,修改代码

    静态语言:编译时已经确定好代码,运行过程中不能修改

    如果我们想要限制实例的属性怎么办?比如,只允许对Person实例添加name和age属性。

    为了达到限制的目的,Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性:

    >>> class Person(object):
        __slots__ = ("name", "age")
    
    >>> P = Person()
    >>> P.name = "老王"
    >>> P.age = 20
    >>> P.score = 100
    Traceback (most recent call last):
      File "<pyshell#3>", line 1, in <module>
    AttributeError: Person instance has no attribute 'score'
    >>>

    注意:

    • 使用__slots__要注意,__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的
    In [67]: class Test(Person):
        ...:     pass
        ...:
    
    In [68]: t = Test()
    
    In [69]: t.score = 100
  • 相关阅读:
    logging模块、sys模块、shelve模块
    re模块、hashlib模块
    包、常用模块
    模块
    迭代器、生成器、递归、二分法
    函数对象、函数嵌套、名称空间与作用域、闭包函数、装饰器
    函数
    文件处理
    字符编码
    Djiango导读
  • 原文地址:https://www.cnblogs.com/wilson-wu/p/8329568.html
Copyright © 2020-2023  润新知