• 类的内置方法


    内置方法之 __str__()

      可以改变返回值,以前是地址,那么使用这个方法之后,打印的就是这个内容,而不是地址,使用print方法的时候,默认调用这个方法

    class A():
        def __init__(self,name,price,period):
            self.name = name
            self.price= price
            self.period= period
        def __str__(self):    # 当定义这个方法之后,类外的调用对象参数的print就会变成调用这个方法

    # '''打印这个对象的时候 自动触发__str__'''
    # '''使用%s进行字符串的拼接的时候 自动触发__str__'''

            return '%s,%s,%s'%(self.name,self,price,self,period)
    python = Course('python',40000,'6 month')
    print(python)

    内置方法之__repr__()

      功能和str功能一致,但是repr是备胎,只有找不到str的时候才调用这个方法

    class Course:
        def __init__(self,name,price,period):
            self.name = name
            self.price = price
            self.period = period
    
        def __repr__(self):   # 备胎
            return '%s,%s,%s'%(self.name,self.price,self.period)
    
        def __str__(self):
            return self.name
    
    python = Course('python',25000,'6 months')
    print(python)
    print('course %s'%python)
    print(f'course {python}')
    print(repr(python))
    print('course %r'%python)
    # 如果str存在,repr也存在
    # 那么print(obj)和使用字符串格式化format,%s这两种方式 调用的都是__str__
    # 而repr(obj)和%r格式化字符串,都会调用__repr__
    # 如果str不存在,repr存在
    # 那么print(obj),字符串格式化format,%s,%r 和repr(obj)都调用__repr__
    # 如果str存在,repr不存在
    # 那么print(obj)和使用字符串格式化format,%s这两种方式 调用的都是__str__
    # repr(obj)和%r格式化字符串 都会打印出内存地址

    在类的继承中的查找:

     class Course(object):
        def __init__(self,name,price,period):
            self.name = name
            self.price = price
            self.period = period
    
        def __repr__(self):   # 备胎
            return '%s,%s,%s'%(self.name,self.price,self.period)
    
        # def __str__(self):
        #     return self.name
    
    class Python(Course):
        pass
        # def __repr__(self):   # 备胎
        #     return '%s--%s--%s'%(self.name,self.price,self.period)
    
        # def __str__(self):
        #     return '全栈开发 :'+self.name
    
    py20 = Python('python',25000,'6 months')
    print(py20)
    # 打印对象 先走自己的str,如果没有,走父类的,如果除了object之外的所有父类都没有str
    # 再回来,找自己的repr,如果自己没有,再找父类的
    
    # repr是str的备胎
    # 和所有的字符串格式化以及直接打印这个对象相关
    # str(obj),repr(obj)

    这两个内置方法的作用:

    # 有了repr或者str在打印对象的时候 就不会显示用户不关心的内存地址了
    # 增强了用户的体验 在程序开发的过程中
    # 如果我们需要频繁打印对象中的属性,需要从类的外部做复杂的拼接,实际上是一种麻烦
    # 如果这个拼接工作在类的内部已经完成了,打印对象的时候直接就能显示

    内置方法之__new__()

      new方法时构造方法

     class Foo:
         def __new__(cls, *args, **kwargs):
             print('in new')   # 先执行
             obj = object.__new__(cls)
             print(obj)
             return obj
    
         def __init__(self):
             print('init',self)    # 后执行
    
    Foo()   # 如果有new 方法,那么会先执行new方法,然后再执行init方法

    # 实例化一个Foo的对象
    # 先开辟一块儿空间,使用的是Foo这个类内部的__new__
    # 如果我们的Foo类中是没有__new__方法的
    # 调用object类的__new__方法了

     class Foo(object):
         def __new__(cls, *args, **kwargs): # cls永远不能使self参数,因为#self在之后才被创建
             obj = object.__new__(cls)   # self是在这里被创造出来的
             print('new : ',obj)
             return obj
         def __init__(self):
             print('init',self)
    
     Foo()
    # 在使用self之前,都还有一个生产self的过程
        # 就是在内存中开辟一块属于这个对象的空间,并且在这个空间中存放一个类指针
        # 以上就是__new__做的所有事情

    单例模式

    # 设计模式 - 单例模式
    # 一个类 有且只能有一个实例
    
    class A:pass
    a1 = A()
    a2 = A()
    print(a1)
    print(a2)
    
    class A:
        __flag = None
        def __new__(cls, *args, **kwargs):
            if cls.__flag is None:
                cls.__flag = object.__new__(cls)
            return cls.__flag
    
        def __init__(self,name=None,age=None):
            self.name = name
            if age:
                self.age = age
    
    a1 = A('alex',84)
    print(a1)
    a2 = A('alex',83)
    print(a2)
    a3 = A('alex')
    print(a3)
    print(a1.age)
    
    # 保证一个类无论 被实例化多少次,只开辟一次空间,始终使用的是同一块内存地址

    内置方法之__del__()

    # __del__方法
    # python解释器
    import time
    class A:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __del__(self):
            # 只和del obj语法有关系,在执行del obj之前会来执行一下__del__中的内容
            print('执行我啦')
    
    a = A('alex',84)
    print(a.name)
    print(a.age)
    # del a   # 这个变量已经没了
    time.sleep(1)
    # 在所有的代码都执行完毕之后,所有的值都会被python解释器回收
    
    # python解释器清理内存
        # 1.我们主动删除 del obj
        # 2.python解释器周期性删除
        # 3.在程序结束之前 所有的内容都需要清空
    
    import time
    class A:
        def __init__(self,path):
            self.f = open(path,'w')
        def __del__(self):
            '''归还一些操作系统的资源的时候使用'''
            '''包括文件网络数据库连接'''
            self.f.close()
    
    
    a = A('userinfo')
    time.sleep(1)

    with的上下文处理

    # with的上下文处理
    class File:
        def __enter__(self):  # 在with执行之前先执行
            print('start')
    
        def __exit__(self, exc_type, exc_val, exc_tb):# with执行完之后执行
            print('exit')
    
    with File():
        print('wahaha')
    
    
    class myopen:
        def __init__(self,path,mode='r'):
            self.path = path
            self.mode = mode
    
        def __enter__(self):# 在with执行之前先执行
            print('start')
            self.f = open(self.path,mode=self.mode)
            return self.f
    
        def __exit__(self, exc_type, exc_val, exc_tb):# with执行完之后执行
            self.f.close()
            print('exit')
    
    with myopen('userinfo','a') as f:
        f.write('hello,world')
  • 相关阅读:
    字节流与字符流的区别?
    启动一个线程是用run()还是start()?
    Java中的异常处理机制的简单原理和应用?
    java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类?
    Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法? stop()和suspend()方法为何不推荐使用?
    运行时异常与一般异常有何异同?
    常用清除浮动的方法,如不清除浮动会怎样?
    多线程有几种实现方法?同步有几种实现方法?
    你所知道的集合类都有哪些?主要方法?
    至少两种方式实现自适应搜索?
  • 原文地址:https://www.cnblogs.com/mk-lovefreedom/p/10679019.html
Copyright © 2020-2023  润新知