首页 > 编程语言 > 详细

python-面向对象-双下方法

时间:2019-08-04 23:23:11      阅读:173      评论:0      收藏:0      [点我收藏+]

__str__和__repr__

class Course(object):

    def __init__(self, name, price):
        self.name = name
        self.price = price

    def __str__(self):
        return "func is __str__ ,课程:{},价格:{}".format(self.name, self.price)

#
python = Course("python", 25000)
print(python)  # func is __str__ ,课程:python,价格:25000
print("%s" % (python))  # func is __str__ ,课程:python,价格:25000
print([python])  # [<__main__.Course object at 0x000001CAEB38F438>]


class Course(object):

    def __init__(self, name, price):
        self.name = name
        self.price = price

    def __repr__(self):
        return "func is __repr__ ,课程:{},价格:{}".format(self.name, self.price)


python = Course("python", 25000)
print(python)  # func is __repr__ ,课程:python,价格:25000
print("%r" % (python))  # func is __repr__ ,课程:python,价格:25000
print([python])  # [func is __repr__ ,课程:python,价格:25000]

python = Course("python", 25000)
class Course(object):

    def __init__(self, name, price):
        self.name = name
        self.price = price

    def __str__(self):
        return "func is __str__ ,课程:{},价格:{}".format(self.name, self.price)

    def __repr__(self):
        return "func is __repr__,课程:{},价格:{}".format(self.name, self.price)


python = Course("python", 25000)
print(python)  # func is __str__ ,课程:python,价格:25000
print("%s" % (python))  # func is __str__ ,课程:python,价格:25000
print([python])  # [func is __repr__,课程:python,价格:25000]

print(repr(python))  # func is __repr__,课程:python,价格:25000
print("%r" % (python))  # func is __repr__,课程:python,价格:25000

总结:

# 如果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的备胎
和所有的字符串格式化以及直接打印这个对象相关

有了repr或者str在打印对象的时候 就不会显示用户不关心的内存地址了
增强了用户的体验 在程序开发的过程中
如果我们需要频繁打印对象中的属性,需要从类的外部做复杂的拼接,实际上是一种麻烦
如果这个拼接工作在类的内部已经完成了,打印对象的时候直接就能显示

__new__ 和__del__

__new__ 构造方法 生产对象的时候用的 - 单例模式.
__del__ 析构方法 在删除一个对象之前用的 - 归还操作系统资源.

__new__

class Foo(object):
    def __new__(cls, *args, **kwargs):  # 这里不能将cls换成self.原因在这里,self还没有被创建出来
       print("创建对象呀!")  # 先执行
       obj = object.__new__(cls) # self被创建出来
       print(obj)  # <__main__.Foo object at 0x00000158F978C9E8>
       return obj


    def __init__(self):
        print("初始化!!")  # 后执行
        print(self) # <__main__.Foo object at 0x00000158F978C9E8>


f = Foo()
'''
创建对象呀!
<__main__.Foo object at 0x00000158F978C9E8>
初始化!!
<__main__.Foo object at 0x00000158F978C9E8>
'''

实例化一个Foo对象,先开辟一块空间,使用的是Foo这个内部的__new__,如果内部没有这个__new__方法,则会调用object类中的__new__方法

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

单例模式

一个类 有且只能有一个实例

class Foo(object):
    __flag = None

    def __new__(cls, *args, **kwargs):
        if cls.__flag is None:
            obj = object.__new__(cls)
            cls.__flag = obj
            
        return cls.__flag

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

__del__

class Foo(object):
    def __init__(self, name,age):
        self.name = name
        self.age = age


    def __del__(self):
        print("执行我了")
        print("ddabhjdab")


f = Foo("Tom", 45)
print(f.__dict__)  # {'name': 'Tom', 'age': 45}
del f.name   # 只和del obj语法有关系,在执行del obj之前会来执行一下__del__中的内容
print(f.__dict__)
'''
{'age': 45}
执行我了
'''

文件的操作

class File(object):
    def __init__(self, path):
        self.f = open(path, 'w',encoding='utf-8')

    def __del__(self):
        self.f.close()


f = File("XXXX")

在所有的代码都执行完毕之后,所有的值都会被python解释器回收

python解释器清理内存

  1. 我们主动的去删除 del obj
  2. python解释器周期性删除
  3. 在程序结束之前,所有的内容都需要进行清空

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

class Foo(object):
    def __init__(self, name):
        self.name = name

    def __call__(self, *args, **kwargs):
        print("name " + self.name)


# f = Foo("Tom")
# f()  # name Tom

Foo("Mack")()  # name Mack   # 对象+()就会调用__call__()方法

with处理上下文

class Foo(object):
    def __enter__(self):
        print("开始")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("结束!")


with Foo():
    print('aaaa')
'''
开始
aaaa
结束!
'''

文件操作

class Myopen(object):

    def __init__(self,path,mode):
        self.path = path
        self.mode = mode

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


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


with open("test", 'a') as file:  # file == self.f
    file.write('hello world')

pickle文件操作

dump

import pickle


class PickleDump(object):
    def __init__(self, path, mode):
        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 PickleDump("pickle_file", 'ab') as file:
    file.dump("abcde")
    file.dump("abcde")
    file.dump("abcde")
    file.dump("abcdea")

load

import pickle


class PickleLoad(object):
    def __init__(self, path, mode):
        self.mode = mode
        self.path = path

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

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

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


with PickleLoad('pickle_file', 'rb') as file:
    for read_line in file.load():
        print(read_line)

实现一个装饰器

class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __enter__(self):
        print("开始了")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("结束了")


with Foo("Tom", 45):
    print("func")


'''
开始了
func
结束了
'''

python-面向对象-双下方法

原文:https://www.cnblogs.com/yangchangjie150330/p/10642845.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!