zoukankan      html  css  js  c++  java
  • python装饰器高级用法

    1.装饰类

      下面,直接来看代码是如何实现装饰类的:

    def decorator(aClass):
        class newClass:
            def __init__(self, age):
                self.total_display   = 0
                self.wrapped         = aClass(age)
            def display(self):
                self.total_display += 1
                print("total display", self.total_display)
                self.wrapped.display()
        return newClass
    
    @decorator # 接受一个类参数
    class Bird:
        def __init__(self, age):
            self.age = age
        def display(self):
            print("My age is",self.age)
    
    eagleLord = Bird(5)
    for i in range(3):
        eagleLord.display()

      在decorator中,我们返回了一个新类newClass。在新类中,我们记录了原来类生成的对象(self.wrapped),并附加了新的属性total_display,用于记录调用display的次数。我们也同时更改了display方法。

      通过修改,我们的Bird类可以显示调用display的次数了

    2.装饰器捕捉异常

      有一个check类,其中有方法read_value()。由于某些原因,方法read_value有可能抛出异常而使程序崩溃,所以需要对整个方法做try....except处理,如:

      没有捕捉异常之前:

    class check(object):
        def __init__(self):
            pass
    
        def receive(self):
            print('receive from exception.')
    
        def read_value(self):
            print('here i will do something')
            'a' + 1  # 这里会报异常
    
    c = check()
    c.read_value()

      加了try....except捕捉异常后:

    class check(object):
        def __init__(self):
            pass
    
        def receive(self):
            print('receive from exception.')
    
        def read_value(self):
            try:
                print('here i will do something')
                'a' + 1
            except Exception as e:
                print(e)
    
    c = check()
    c.read_value()

      虽然程序不会报出异常,但这样处理,有些丑陋。来看看装饰器是如何处理的:

    def catch_exception(func):
        def wrapper(*args,**kwargs):
            try:
                u = func(*args,**kwargs)
                return u
            except Exception:
                return 'an exception raised'
        return wrapper
    
    
    class check(object):
        def __init__(self):
            pass
    
        def receive(self):
            print('receive from exception.')
    
        @catch_exception
        def read_value(self):
            print('here i will do something')
            'a' + 1
    
    c = check()
    c.read_value()

      很好,使用装饰器,来装饰函数,这样使我们的代码更加pythonic。但是,如果程序报出异常后,调用类中的另外一个方法,那怎么办?很简单,给装饰器加上一个参数self:

    def catch_exception(func):
        def wrapper(self,*args,**kwargs):
            try:
                u = func(self,*args,**kwargs)
                return u
            except Exception:
                self.receive()
                return 'an exception raised'
        return wrapper
    class check(object):
        def __init__(self):
            pass
        
        def receive(self):
            print('receive from exception.')
        
        @catch_exception
        def read_value(self):
            print('here i will do something')
            'a' + 1
            
    c = check()
    c.read_value()

      有木有感觉,很神奇。

     3.装饰器注意事项

     3.1函数的属性会发生变化

      装饰器动态创建的新函数替换原来的函数,但是,新函数缺少很多原函数的属性,如docstring和名字。

      

  • 相关阅读:
    【记录】用了七年eclipse突然改用IntelliJ IDEA------- 痛并快乐着
    【记录】集合Collection和Map整理 (看这一篇就够了)
    group by语句报with sql_mode=only_full_group_by错误
    linux下安装mysql二进制版本(5.6.34)
    linux下安装mysql二进制版本(5.7.11)
    表空间传输-例子2(full transportable)
    表空间传输-例子3(rman-transport获取传输表空间文件)
    transport_datafiles与FLASHBACK_SCN不能一起使用
    表空间传输数据文件转换
    12C添加pdb后创建用户没有相应的表空间
  • 原文地址:https://www.cnblogs.com/vipchenwei/p/7224491.html
Copyright © 2011-2022 走看看