• python学习笔记 day27 内置方法


    1. __str__() 

    先说结论: 内置的类方法和内置函数之间有千丝万缕的关系;

                       当直接打印一个对象print(obj)  或者 print(str(obj)) 或者 %s都是去调用该对象的__str__()方法;

                       如果本类未实现__str__()方法就去调用本类实现的__repr__()方法,找不到再去调父类的__str__()方法;

                       内置的类方法一旦有返回值,必须是str类型的;

    class Teacher():
        def __init__(self,name):
            self.name=name
        def __str__(self):
            return "Teacher's obj is %s"%self.name  # 内置的类方法__str__()一旦有返回值,一定是str类型的!
    teacher=Teacher('xuanxuan')
    print(teacher)  # 直接打印对象其实是调用该对象的__str__()方法;
    print(str(teacher)) # str(obj)也是去调用对象obj的__str__()方法
    print(">>>%s"%teacher) # %s 也是去调用这个对象的__str__()方法

    运行结果:

    2. __repr__(): 

    先说结论:

                 直接打印repr(obj)  即print(repr(obj)) 或者 直接%r 都是去调用对象的内置类方法__repr__();

                 内置的类方法__repr__()一旦有返回值一定是字符串类型,否则会报类型错误;

                 内置的类方法__repr__()是内置类方法__str__()的备胎,就是当对象去调用__str__()但是本类未实现__str__()时会去调用本类的__repr__()方法,但是反过来不行;

    class Teacher():
        def __init__(self,name,salary):
            self.name=name
            self.salarry=salary
        def __repr__(self):
            return str(self.__dict__)  # 在内置类方法__repr__()中调用__dict__()内置方法就是以字典形式打印对象的属性;
    
    teacher=Teacher('xuanxuan',13000)
    print(teacher)  # 直接打印对象其实是去调用对象的__str__()方法,但是本类未实现__str__() 就调用__str__()的备胎__repr__()
    print(repr(teacher))  # repr(obj)是在调用对象的内置类方法__repr__()
    print(">>>%r"%teacher) # %r 也是在调用对象的__repr__()方法

    运行结果:

     3. __len__():

    当调用len()方法时,其实是在调用内置的类方法__len__(),(注意这个内置方法__len__()在object父类中是没有被实现的,也就是如果本类不实现__len__()方法就会报错)

    class Classes():
        def __init__(self,name):
            self.name=name
            self.students=[] # 把学生存成一个列表
        def __len__(self):
            return len(self.students)  # 班级这个类中实现的__len__()其实是在计算这个班级的人数(定制类)
    
    s9_python=Classes("python 9期课程班")
    s9_python.students.append("璇璇")
    s9_python.students.append('嘻嘻')
    print(len(s9_python))  # len()方法其实是在调用对象的__len__()方法,但是在这个内置类方法中实现的其实在计算班级对象的students属性(是一个列表)的长度,也即班级中学生人数

    运行结果:

    4. __del__() 析构函数

    其实python解释器内部有一种垃圾回收机制,当这个变量不再被使用时 就会被释放,调用内置类方法__del__() 先执行析构函数中的代码,然后删除这个对象;

    析构函数一般是在释放对象前,做一个收尾工作;

    执行del(obj)其实是在执行__del__()方法

    class A():
        def __del__(self):
            print("被删除之前我被执行啦")
    a=A()
    del(a)  # 执行del()就是在执行内置类方法__del__()

    运行结果:

    再来看一个例子:

    即使没有调用del(a) 由于后面a对象没有在被使用,所以会被释放,执行__del__()析构函数

    import time
    class A():
        def __del__(self):
            print("被删除之前我被执行啦")
    a=A()
    time.sleep(3) # 先暂停3秒,然后a不再被使用,就会去调用__del__()方法(即使没有del(a)),把a对象释放掉,所以还是会打印那句话
    # del(a)  # 执行del()就是在执行内置类方法__del__()

    运行结果:

    再来看一个有应用场景的,比如我们使用一个对象的属性执行的操作是去打开文件(注意打开文件其实是在执行两个操作,1.在操作系统中打开了一个文件,2. 拿到了文件操作符),当这个对象不再被执行时,就会被释放掉,显然该对象的属性也会被释放,内存中的文件操作符也会被释放,但是文件并不会被关闭,但是对象在被释放时会去执行__del__() 我们就可以在析构函数中执行关闭文件的操作,做一些收尾,执行完之后才会去把这个对象删掉(从内存中释放)

    class A():
        def __del__(self):
            self.f.close()  # 在释放对象之前,先执行对象的属性f关闭文件
            print("文件被关闭了")
    a=A()
    a.f=open("info")

    运行结果:

    5. __call__()

    对象() 这种形式就会自动调用__call__()方法

    class A:
        def __call__(self):
            print("当对象加上括号时我就被调用执行了~")
    a=A()
    a()  # 此时会执行__call__()方法

    运行结果:

    talk is cheap,show me the code
  • 相关阅读:
    《Effective Java》第9章 异常
    《Effective Java》第7章 方法
    《Effective Java》第6章 枚举和注解
    《Effective Java》第5章 泛型
    《Effective Java》第4章 类和接口
    《Effective Java》第3章 对于所有对象都通用的方法
    使用Spring加载properties配置文件.md
    第7章 插件的使用和写法
    第6章 jQuery与Ajax的应用
    第5章 jQuery对表单、表格的操作及更多应用
  • 原文地址:https://www.cnblogs.com/xuanxuanlove/p/9692306.html
Copyright © 2020-2023  润新知