内置方法

内置方法 双下方法 魔术方法

都是python的对象内部自带的

并且都不需要我们自己去调用它

1.

__str__

__repr__

class Course:
    def __init__(self,name,price,period):
        self.name = name
        self.price = price
        self.period = period
    def __str__(self):
        '''打印这个对象的时候 自动触发__str__'''
        '''使用%s进行字符串的拼接的时候 自动触发__str__'''
        return '%s,%s,%s'%(self.name,self.price,self.period)

python = Course('python',25000,'6 months')
print(python)              #python,25000,6 months
print('course %s'%python)  #course python,25000,6 months
print(f'course {python}')  #course python,25000,6 months
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.period

python = Course('python',25000,'6 months')
print(python)              #6 months  
print('course %s'%python)  #course 6 months
print(f'course {python}')  #course 6 months
print(repr(python))        #python,25000,6 months
print('course %r'%python)  #course python,25000,6 months

 如果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)    #全栈开发 :python
打印对象(1)
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)    #python
打印对象(2)
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)    #python--25000--6 months
打印对象(3)
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)    #python,25000,6 months
打印对象(4)

打印对象 先走自己的str,如果没有,走父类的,如果除了object之外的所有父类都没有str

再回来,找自己的repr,如果自己没有,再找父类的

repr是str的备胎

和所有的字符串格式化以及直接打印这个对象相关

str(obj),repr(obj)

流畅的python - repr

2.

__new__ 构造方法  生产对象的时候用的 - 单例模式

__del__ 析构方法  在删除一个对象之前用的 - 归还操作系统资源

__new__ 

class Foo:
    def __new__(cls, *args, **kwargs):
        print('in new')   # 先执行   in new
        obj = object.__new__(cls)
        print(obj)        # <__main__.Foo object at 0x000001CF7E75D780>
        return obj

    def __init__(self):
        print('init',self)    # 后执行  init <__main__.Foo object at 0x000001CF7E75D780>
Foo()

# 实例化一个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)  #new :  <__main__.Foo object at 0x000002150A77D128>
        return obj
    def __init__(self):
        print('init',self)  #init <__main__.Foo object at 0x000002150A77D128>

Foo()
# 在使用self之前,都还有一个生产self的过程
    # 就是在内存中开辟一块属于这个对象的空间,并且在这个空间中存放一个类指针
    # 以上就是__new__做的所有事情

单例模式   一个类 有且只能有一个实例

class A:pass
a1 = A()
a2 = A()
print(a1)  #<__main__.A object at 0x0000019B72F8AFD0>
print(a2)  #<__main__.A object at 0x0000019B72F8D048>
#不同的内存地址
class A:
    __flag = None
    def __new__(cls, *args, **kwargs):
        if cls.__flag is None:  #实例化一次以后,__flag不再是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)     #<__main__.A object at 0x000001A26908D9E8>
a2 = A('alex',83)
print(a2)     #<__main__.A object at 0x000001A26908D9E8>
a3 = A('alex')
print(a3)     #<__main__.A object at 0x000001A26908D9E8>
print(a1.age) #83

# 保证一个类无论 被实例化多少次,只开辟一次空间,始终使用的是同一块内存地址

__del__

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)    #alex
print(a.age)     #84
# del a   # 这个变量已经没了
time.sleep(1)    #停顿一秒后执行 __del__  打印初‘执行我了’

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)

3.

__call__

源码里用比较多 Flask web框架

对象()自动触发__call__中的内容

lass A:
    def call(self):
        print('in call')
    def __call__(self, *args, **kwargs):
        print('in __call__')

A()()        #in __call__
obj = A()
obj()       #in __call__
obj.call()  #in call

with的上下文处理   __entrt__   __exir__

class File:
    def __enter__(self):
        print('start')

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit')

with File():
    print('wahaha')

在一个函数的前后添加功能

利用使用 装饰器函数中的内容

class myopen:
    def __init__(self,path,mode='r'):
        self.path = path
        self.mode = mode

    def __enter__(self):
        print('start')
        self.f = open(self.path,mode=self.mode)
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()
        print('exit')

with myopen('userinfo','a') as f:  #as f 就是__enter__ 的返回值
    f.write('hello,world')

#在执行写入‘hello,world’之前运行 __enter__ 即打开文件,打印‘start’,之后执行__exit__ 关闭文件,打印‘exit’
import pickle
class MypickleDump:
    def __init__(self,path,mode = 'ab'):
        self.path = path
        self.mode = mode

    def __enter__(self):
        self.f = open(self.path,self.mode)
        return self

    def dump(self,obj):
        pickle.dump(obj,self.f)

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()


with MypickleDump('pickle_file') as pickle_obj:
    pickle_obj.dump({1,2,3})
    pickle_obj.dump({1,2,3})
pickle 写入
class MypickelLoad:
    def __init__(self,path,mode='rb'):
        self.path = path
        self.mode = mode

    def __enter__(self):
        self.f = open(self.path,self.mode)
        return self

    def loaditer(self):
        while True:
            try:
                ret = pickle.load(self.f)
                yield ret
            except EOFError:
                break

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()
#

with MypickelLoad('pickle_file') as mypic:
    for obj in mypic.loaditer():
        print(obj)
pickle 读出
class MypickleDump:
    def __init__(self,path,mode = 'ab'):
        self.path = path
        self.mode = mode

    def __enter__(self):
        self.f = open(self.path,self.mode)
        return self

    def dump(self,obj):
        pickle.dump(obj,self.f)

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.f.close()

with MypickleDump('pickle_file') as obj:
    obj.dump({1,2,3,4})

with MypickelLoad('pickle_file') as obj:
   for i in  obj.loaditer():
       print(i)
import time
class Timer:
    def __enter__(self):
        self.start = time.time()
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(time.time() - self.start)

def func():
    print('wahaha')
    time.sleep(1)
    print('qqxing')


with Timer():
    func()
原文地址:https://www.cnblogs.com/Xiao_Xu/p/10643479.html