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

一.
__str__/__repr__     

where:在打印对象 ( print(obj) / print(repr(obj) )或用%s,%r格式化输出时候自动执行
how:有了repr或者str在打印对象的时候 就不会显示用户不关心的内存地址了
        增强了用户的体验 在程序开发的过程中
        如果我们需要频繁打印对象中的属性,需要从类的外部做复杂的拼接,实际上是一种麻烦
        如果这个拼接工作在类的内部已经完成了,打印对象的时候直接就能显示
结果:    如果 不实现str/repr方法,那么对象打印出来只是一串地址

 如果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 Courese:
    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=Courese('python',25000,'6months')
print(python)    #没有输出格式,>>>><__main__.Courese object at 0x000002B48D97DE80>
print(python)    #有__str     >>>python
print(python)    #有 __repr    >>>python,25000,6months
print(python)    #都有时,执行__str不执行__repr,>>>python
print(repr(python))     #>>>都有   ython,25000,6months
print('course %r'%python)   #都有   course python,25000,6months

又是我们在继承中会遇到有str_与repr_情况,子类父类的不同方法,需要我们选择:
对于当前类,如果自己没有str,就找父类的str.如果父类都没有,那开始找repr,在没有继续向上找
二.

__init__

类实例化对象的初始化方法,传参给self生成对象obj

__new__构造方法 生产对象的时候用-----

构造方法,类创建对象的第一步,开辟对象空间,创建空对象,存放类指针,整个函数方法创造了self

构造方法__new__的执行是由创建对象触发的,即:对象 = 类名()

 1 class Base(object):
 2     def __new__(cls, *args, **kwargs):
 3         '''
 4         构造方法:开辟空间,创键空对象self
 5         :param args:
 6         :param kwargs:
 7         :return:
 8         '''
 9         return object.__new__(cls)   #self
10     def __init__(self):
11         '''
12         初始化方法,给空self传参,创造实例化对象
13         '''
14         self.x=1
15 obj=Base()   #先执行new方法,在init方法实例
16 print(obj)
17 print(obj.x)

单例模式_设计模式_一个类只能有一个实例化对象
一个类无论实例化多少次,只开辟一次空间,始终用同一块内存地址

 1 class A:
 2     __flag=None                         #增加限制
 3     def __new__(cls, *args, **kwargs):  #生产self的动作
 4         if cls.__flag is None:          #回应,条件设置限制
 5             cls.__flag=object.__new__(cls) #这里才开辟空间创造self
 6         return cls.__flag               #返回实际为self空间,存储类指针
 7     def __init__(self,name=None,age=None):
 8         self.name=name
 9         if age:
10             self.age=age
11 a1=A('alex',84)
12 print(a1)
13 a2=A('alex',83)            #a1与a2相同的地址
14 print(a2)
15 print(a1.age)              #此处a2已经覆盖a1>>>83

三.
__del__析构方法 在删除一个对象之前用的 _归还操作系统资源
 python解释器清理内存
       1.我们主动删除 del obj
       2.python解释器周期性删除
       3.在程序结束之前 所有的内容都需要清空

import time
class A:
    def __init__(self,path):
        self.f=open(path,'w')
    def __del__(self):   #只与del obj 相关,执行删除对象前先执行者动作
        #归还操作系统资源,包括文件网络数据库连接,在程序执行完后,自动执行
        self.f.close()
a=A('userinfo')

 注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。


四.
__call__源码中用的比较多,对象() 会自动触发__call__中的内容

构造方法__new__的执行是由创建对象触发的,即:对象 = 类名()

而对于 call 方法的执行是由对象后加括号触发的,即:对象() 或者 类()(),触发执行类中的__call__方法

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

A()()             #in __call__
obj = A()
obj()             #in __call__ 对象加括号,直接调用__call__的动作
obj.call()        #in call

五.with 上下文处理               文件操作类
with 语句,就是__enter__,执行前动作,__exit__执行后动作

在一个函数的前后添加功能,类似装饰器函数中的内容

 1 import pickle                           #调用pickle模块文件操作
 2 class Mypicledump:                      #创建文件写入的类
 3     def __init__(self,path,mode='ab'):  #文件操作必要属性传入
 4         self.path=path
 5         self.mode=mode
 6     def __enter__(self):                #函数动作前的打开文件操作
 7         self.f=open(self.path,self.mode)
 8         return self                     #返回要操作的文件
 9     def dump(self,obj):
10         pickle.dump(obj,self.f)         #写入文件的动作
11     def __exit__(self, exc_type, exc_val, exc_tb):
12         self.f.close()                  #写入结束后关闭文件
13 with Mypicledump('pickle_file') as obj:  #实例化一个文件做对象,对象句柄为obj
14     obj.dump({1,2,3,4})       #对象(句柄)加点.加动作函数(包含写入参数)
15 
16 
17 class MypickelLoad:                     #定义文件查看类
18     def __init__(self,path,mode='rb'):  #必要属性传入
19         self.path=path
20         self.mode=mode
21     def __enter__(self):                #动作前打开文件
22         self.f=open(self.path,self.mode)
23         return self                     #self为打开待执行的文件
24     def loaditer(self):                 #读取文件用生成器节省内存
25         while True:
26             try:                        #迭代器超出范围错误处理
27                 ret = pickle.load(self.f)  #实际读取动作
28                 yield ret               #生成器
29             except EOFError:
30                 break
31     def __exit__(self, exc_type, exc_val, exc_tb):
32         self.f.close()                   #结束文件操作
33 with MypickelLoad('pickle_file')as mypic:  #创建读取文件类的对象,文件句柄mypic
34     for obj in mypic.loaditer():           #用for循环查看对象动作后生成器内容
35         print(obj)                         #查看内容

文件操作的写入,读取模板,创建类的对象执行即可使用

六.__dict__

把对象的属性与值格式化为字典输入查看所有属性(包括隐藏属性)

print(obj.__dict__)

1 class School:
2     def __init__(self,name,addr,type):
3         self.name=name
4         self.addr=addr
5         self.__tpye=type
6 obj=School('老男孩','北京','教育')
7 print(obj.__dict__)
8 {'name': '老男孩', 'addr': '北京', '_School__tpye': '教育'}

七,item

 1 class Foo:
 2     def __init__(self,name):
 3         self.name=name
 4 
 5     def __getitem__(self, item):
 6         print(self.__dict__[item])
 7 
 8     def __setitem__(self, key, value):
 9         self.__dict__[key]=value
10         
11     def __delitem__(self, key):
12         print('del obj[key]时,执行我方法')
13         self.__dict__.pop(key)
14         
15     def __delattr__(self, item):
16         print('del obj.key时,执行我方法')
17         self.__dict__.pop(item)
18 
19 f1=Foo('666')
20 print(f1.name)     #查看属性
21 f1['age']=18       #添加属性用setitem  方法
22 print(f1.age)      
23 print(f1[age])    #查看属性调用getitem   方法
24 f1['name']='alex'     #改变属性,setitem  方法
25 print(f1.__dict__)
26 del f1['age']         #删除属性,调用delitem 方法
27 print(f1.__dict__)
28 #del f1.age             #删除属性,调用delattr  方法
29 #print(f1.__dict__)        

八.



 

 

原文地址:https://www.cnblogs.com/OB19227/p/10642935.html