首页 > 其他 > 详细

7 上下文管理器 魔术方法

时间:2020-12-07 09:36:36      阅读:37      评论:0      收藏:0      [点我收藏+]

1.上下文管理器

2.模式方法

 

1.上下文管理器

1).python的上下文管理协议:包含__enter__() 、__exit__()

2)上下文管理器:支持"上下文管理的协议"的对象(同时支持__enter__()、__exit__())

3)with 语句操作上下文管理器对象

with object as o:

        pass

? with后的object是上下文管理器的对象;o是__enter__()的返回值

举例:在执行with里的语句之前,先执行__enter__(),再执行with中的语句,最后执行__exit__()-------即上下文管理器

"""
python上下文管理的协议:包含__enter__() 、__exit__()
上下文管理协议:支持"上下文管理的协议"的对象(同时支持__enter__()、__exit__())
with 后面跟的是上下文管理器的对象
"""
# 自定义上下文管理器---包含__enter__()、__exit__()
class MyClass(object):

    def __enter__(self):
        print("enter is running...")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("exit is running...")

def main():
    # 实例对象
    obj = MyClass()
    with obj as o:
        print("with is running...")

if __name__ == __main__:
    main()
"""
enter is running...
with is running...
exit is running...
"""

 

4)常见的上下文管理器

open(file)

with open("上下文管理器.txt","w",encoding="utf8") as f:
    f.write("python")

为什么open能够被with操作?看看open()的返回值包含哪些属性:

f = open("上下文管理器.txt") # f就是一个上下文管理器
print(dir(f))
"""
... ,‘__enter__‘, ‘__eq__‘, ‘__exit__‘, ...
"""

open()的返回值f是一个上下文管理器,所以可以被with操作。

当然,不是上下文管理器,是不能被with操作的!如下:

with 1 as o:
    pass
"""
    with 1 as o:
AttributeError: __enter__
"""

 

5)如果一个对象不是上下文管理器,怎么变成上下文管理器

在继承的新的类中,添加__enter__() 、__exit__() 2个方法即可。

# 一个对象不是上下文管理器,怎么变成上下文管理器: 继承,在新的类中添加2个方法
class Base(object):
    pass

class MyBase(Base):
    def __enter__(self):
        pass
    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

 

2.魔术方法:

在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法

 

1)__str__:

  • 当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印这个方法中return的数据
  • __str__方法需要返回一个字符串,当做这个对象的描写

举例,不写__str__()方法(默认继承object的str方法,返回的是存储地址)

class MyClass(object):

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


def main():
    a = MyClass("zhangsan")
    print(a)

if __name__ == __main__:
    main()  # <__main__.MyClass object at 0x000001B57D0BEC88>

重写__str__()

class MyClass(object):

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

    def __str__(self):
        print("这是对对象的描述...")
        return self.name


def main():
    a = MyClass("zhangsan")
    print(a)

if __name__ == __main__:
    main()  
"""
这是对对象的描述...
zhangsan
"""

 

2).让自定义的类生成的对象(实例)能够使用运算符进行操作

首先来看下list的相加:

def main():
    a = [1, 2, 3]
    b = [4, 5, 6]
    return a + b

if __name__ == __main__:
   print(main()) # [1, 2, 3, 4, 5, 6]

为什么list能够相加?因为list含有__add__属性

def main():
    a = [1, 2, 3]
    b = [4, 5, 6]
    print(hasattr(a,"__add__")) # True
    return a + b

if __name__ == __main__:
   print(main())

 1)对象没有__add__属性,进行相加:报错

class MyClass(object):
    pass

def main():
    a = MyClass()
    b = MyClass()
    return  a + b

if __name__ == __main__:
    print(main()) # TypeError: unsupported operand type(s) for +: ‘MyClass‘ and ‘MyClass‘

对象添加__add__属性

两个对象能不能相加,取决于该对象有没有__add__属性

class MyClass(object):
    def __init__(self, value):
        self.value = value

    def __add__(self, other):
        return self.value + other.value # self 是a对象,other是b对象


def main():
    a = MyClass(11)  
    b = MyClass(23)
    return  a + b

if __name__ == __main__:
    print(main())  # 34

 

3)__del__:Python解释器释放实例对象,调用该方法------析构方法

当删除一个对象时,Python解释器也会默认调用一个方法,这个方法为__del__()方法。在Python中,对于开发者来说很少会直接销毁对象(如果需要,应该使用del关键字销毁)。Python的内存管理机制能够很好的胜任这份工作。也就是说,不管是手动调用del还是由Python自动回收都会触发__del__方法执行

①创建多个对象的时候触发__del__方法,python解释器自动删除对象,释放内存

# python解释器删除不再用的对象 ,释放内存
class MyClass(object):
    def __init__(self):
        print("init is running...")

    def __new__(cls, *args, **kwargs):
        print("new is running...")
        instance = super().__new__(cls)
        return instance
    def __del__(self):
        print("del is running...")

def main():
    a = MyClass()
    b = MyClass()

if __name__ == __main__:
    main()
    print("main() is running...")
"""
new is running...
init is running...
new is running...
init is running...
del is running...
del is running...
main() is running...
"""

②del关键字手动删除

当使用del 把内存的所有应用删除,立刻调用__del__方法

class MyClass(object):
    def __init__(self):
        print("init is running...")

    def __new__(cls, *args, **kwargs):
     #创建对象 分配内存
print("new is running...") instance = super().__new__(cls) return instance def __del__(self):
     #销毁对象
print("del is running...") def main(): a = MyClass() b = MyClass() del a del b

__del__用其他应用场景:在对象被销毁前,进行一些其他操作。

 

4)多态   (面向对象的三大特征:封装、继承、多态)

类型动态

同样的方法,根据不同的对象,会有不同的行为结果。

# 多态
class MyClass(object):

    def music(self):
        print("myclsss music is running...")

class AClass(MyClass):
    def music(self):
        print("Aclass music is running...")

class BClass(MyClass):
    def music(self):
        print("Bclass music is running...")

def func(obj):
    obj.music()  # 只要这个对象有music方法,就会正常调用

if __name__ == __main__:
    m = MyClass()
    a = AClass()
    b = BClass()
   #上面三个对象都有music方法,都可以正常调用该方法 func(a) func(b) func(m)
""" Aclass music is running... Bclass music is running... myclsss music is running... """

 

7 上下文管理器 魔术方法

原文:https://www.cnblogs.com/ananmy/p/14094973.html

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