zoukankan      html  css  js  c++  java
  • 类的内置方法

    内置方法之 __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')
  • 相关阅读:
    (BFS 二叉树) leetcode 515. Find Largest Value in Each Tree Row
    (二叉树 BFS) leetcode513. Find Bottom Left Tree Value
    (二叉树 BFS DFS) leetcode 104. Maximum Depth of Binary Tree
    (二叉树 BFS DFS) leetcode 111. Minimum Depth of Binary Tree
    (BFS) leetcode 690. Employee Importance
    (BFS/DFS) leetcode 200. Number of Islands
    (最长回文子串 线性DP) 51nod 1088 最长回文子串
    (链表 importance) leetcode 2. Add Two Numbers
    (链表 set) leetcode 817. Linked List Components
    (链表 双指针) leetcode 142. Linked List Cycle II
  • 原文地址:https://www.cnblogs.com/mk-lovefreedom/p/10679019.html
Copyright © 2011-2022 走看看