zoukankan      html  css  js  c++  java
  • __内置方法__魔术方法__双下方法__

    一.
    __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__)        

    八.



     

     

  • 相关阅读:
    一行命令搞定node.js 版本升级
    doesn't contain a valid partition table 解决方法
    debian kill 进程等命令
    FastDFS配置说明(中英文)
    FastDFS问题汇总
    FastDFS常见命令
    FastDFS安装配置手册
    windows 与Linux 互传文件
    FtpClient中文乱码问题解决
    windows 配置host
  • 原文地址:https://www.cnblogs.com/OB19227/p/10642935.html
Copyright © 2011-2022 走看看