zoukankan      html  css  js  c++  java
  • Python 5 面向对象进阶

    一、反射

    反射就是用字符串类型的变量名来访问这个变量。

    hasattr,getattr,setattr,delattr

    二、内置方法(魔术方法)

    1、__new__方法(构造方法)

    在实例化对象时,第一步就是为对象开辟一块新的内存空间,然后将这个空间传给init方法。开辟空间就是new方法做的事。

    # 示例:利用new方法构造一个单例模式
    class Single:
        __ISINSTANCE = None
        def __new__(cls, *args, **kwargs):
            if not cls.__ISINSTANCE:  # 第一次实例化
                cls.__ISINSTANCE == object.__new__()
            return cls.__ISINSTANCE
    
        def __init__(self):
            pass

    2、__del__析构方法

    在两种情况下生效,一是使用del,二是python的垃圾回收机制生效时触发。一般析构方法用来释放一些在创建对象时借用的系统资源,如文件资源、网络资源等,这些资源是操作系统层面的,python不能直接控制,所以python的垃圾回收也不会顾及这些,需要析构方法来帮助回收。

    class File:
        def __init__(self, file_path):
            self.f = open(file_path)
        def __del__(self):
            self.f.close()  # 当程序执行完后会自动执行。

    3、__call__方法,通过对象( )调用

    4、__len__方法,len( )函数实际上就是在执行__len__方法

    5、__next__,__iter__

    6、__str__和__repr__

    __repr__会把字符串的两个引号也显示出来。当str和repr两个方法都有时,优先使用str方法,当str方法没有时,str()和print都会使用repr方法。

    7、__hash__

    hash(obj)方法中的obj对象必须定义了__hash__方法。

    hash是一种算法,能把一个值经过一系列计算,转化成一个数字,不同的值转化的数字不同,在一次操作中,相同的值转化成相同的数字。

    字典的寻址和集合的去重就是利用了hash算法。

    字典寻址是先将字典的键保存在任意位置,再hash这个键,得到的数字就是值的内存地址,所以当需要找一个键对应的值的时候,直接hash这个键就能得到内存地址,速度很快。

    集合在保存数据时对每个值进行hash,得到内存地址,将这个值保存在这里,如果后面的值hash得到了相同的结果,再判断两个值是否相等,如果想等就去重,所以集合保存的就是每个值的内存地址,没有重复的。

    8、__eq__

    ==和__eq__方法有关,当进行==比较时就是在执行eq方法,可以定义两个对象相等的条件。

    class Student:
        def __init__(self, name, age):
            self.name = name
            self.age = age
        def __eq__(self, other):
            if self.name == other.name and self.age == other.age:
                return True  # 如果两个对象的name和age都相等就认为这两个对象相等
    
    a1 = Student("a", 1)
    a2 = Student("a", 1)
    print(a1==a2)  # 得到True

    三、抽象类和接口类

    都是用来规范子类中必须实现的方法。无论如何这两种都不能被实例化。

    python中有原生实现抽象类的方法,但是没有原生实现接口类的方法。

    在java中只支持单继承,遵循单继承原则的基类就是抽象类,抽象类中的方法都可以实现。但是java不支持多继承,如果想实现多继承需要使用interface创建接口类,接口类中的方法不能被实现智能pass,接口类都是用来被子类多个继承的。

    from abc import ABC, abstractmethod
    class Te(ABC):
        @abstractmethod
        def test(self):
            pass

    四、其他

    1、__slots__类属性

    如果定义了__slots__类属性,那么这个类在实例化时,就会选择用和__slots__同类型的可迭代对象(如元组)来保存实例变量,而不是使用需要占用很多内存的字典__dict__属性。这样可以节约很多内存,尤其是在实例非常多的时候,避免无谓的内存占用。

    注意:__slots__属性不会被子类继承,所以子类必须重新定义。

    class Test:
        __slots__ = ("m", "k")  # 只能有m和k两个实例变量
  • 相关阅读:
    20165226 2017-2018-4 《Java程序设计》第8周学习总结
    20165226第二次实验
    结对编程练习-四则运算(第一周)
    20165226 2017-2018-4 《Java程序设计》第7周学习总结
    20165226 2017-2018-4 《Java程序设计》第6周学习总结
    实验一 Java开发环境的熟悉
    20165226 2017-2018-3 《Java程序设计》第5学习总结
    第四周课下作业
    第4周学习总结
    第三周学习
  • 原文地址:https://www.cnblogs.com/yinwenjie/p/10847465.html
Copyright © 2011-2022 走看看