类的内置方法

内置方法之 __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')

 

posted @ 2019-04-09 19:07  msKk1  Views(158)  Comments(0Edit  收藏  举报