首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python3 -通过装饰器继承仅在类上执行代码

Python3 -通过装饰器继承仅在类上执行代码
EN

Stack Overflow用户
提问于 2016-06-01 01:36:07
回答 1查看 28关注 0票数 0

我只在一个条件下尝试执行代码:当代码在从AI类继承的类A中执行时。

我希望我能得到的输出如下:

代码语言:javascript
复制
 In [1]: import maintenance 
 In [2]: a = maintenance.A() 
 In [3]: a() 
 Out[3]: Stopping A 
         Executing the common task 
         Cleaning logs 
 In [4]: b = maintenance.B() 
 In [5]: b() 
 Out[5]: Stopping B 
         Executing the common task 

代码如下:

代码语言:javascript
复制
 # module maintenance 

 1     from functools import wraps 
 2 

A要执行的代码是:

代码语言:javascript
复制
 3     def cleaning_logs(): 
 4         print("Cleaning logs") 
 5 

为了不接触A类,我创建了一个装饰器:

代码语言:javascript
复制
 6     def archive_log(func): 
 7         @wraps(func) 
 8         def enhanced_func(*args, **kwargs): 
 9             func(*args,**kwargs) 
10             cleaning_logs() 
11         return enhanced_func 
12 

因为我认为从上面的装饰器中检索类的信息是不可能的,所以我尝试创建一个类装饰器。下面的代码是不完整的,因为这是我的问题:

代码语言:javascript
复制
 13     def cls_archive_log(cls): 
 14         #... Missing Code : I have tried many things 
 15         #... Missing Code : I have tried many things 
 16         setattr(cls, '__call__', archive_log) 
 17         return cls 
 18 

我在下面的代码中使用的这个类装饰器:

代码语言:javascript
复制
 19     @cls_archive_log 
 20     class AI(object): 
 21         def __call__(self): 
 22             self.stop() 
 23             print("Executing the common task") 
 24 
 25     class A(AI): 
 26         def stop(self): 
 27             print('Stopping A') 
 28 
 29     class B(AI): 
 30         def stop(self): 
 31             print('Stopping B') 
 32 

但真的,我已经尝试了所有我能做的类装饰器。

你知道我怎么才能通过装饰者解决我的问题吗?

EN

回答 1

Stack Overflow用户

发布于 2016-06-07 22:10:34

一切都很简单。只需如下设置属性即可:

代码语言:javascript
复制
16 def maintenance(cls):                                                                                                                                                                                                                                                       
17     setattr(cls, '__call__', archive_logs(cls.__call__))                                                                                                                                                                                                                    
18     return cls 

并修饰需要实现维护的类

代码语言:javascript
复制
31 @maintenance                                                                                                                                                                                                                                                                
32 class A(AI):                                                                                                                                                                                                                                                                
33     def stop(self):                                                                                                                                                                                                                                                         
34         print("Stopping A") 

完整代码如下:

代码语言:javascript
复制
#!/usr/bin/env python                                                                                                                                                                                                                                                       

from abc import ABCMeta, abstractmethod                                                                                                                                                                                                                                     
from functools import wraps                                                                                                                                                                                                                                                 

def cleaning_logs():                                                                                                                                                                                                                                                        
    print("Cleaning logs")                                                                                                                                                                                                                                                  

def archive_logs(func):                                                                                                                                                                                                                                                     
    @wraps(func)                                                                                                                                                                                                                                                            
    def enhanced_func(*args, **kwargs):                                                                                                                                                                                                                                     
        func(*args, **kwargs)                                                                                                                                                                                                                                               
        cleaning_logs()                                                                                                                                                                                                                                                     
    return enhanced_func                                                                                                                                                                                                                                                    

def maintenance(cls):                                                                                                                                                                                                                                                       
    setattr(cls, '__call__', archive_logs(cls.__call__))                                                                                                                                                                                                                    
    return cls                                                                                                                                                                                                                                                              

class AI(object):                                                                                                                                                                                                                                                           
    __metaclass__ = ABCMeta                                                                                                                                                                                                                                                 

    @abstractmethod                                                                                                                                                                                                                                                         
    def stop():                                                                                                                                                                                                                                                             
        raise NotImplemtedError('NotImplemtedError')                                                                                                                                                                                                                        

    def __call__(self):                                                                                                                                                                                                                                                     
        self.stop()                                                                                                                                                                                                                                                         
        print("Executing the common AI task")                                                                                                                                                                                                                               

@maintenance                                                                                                                                                                                                                                                                
class A(AI):                                                                                                                                                                                                                                                                
    def stop(self):                                                                                                                                                                                                                                                         
        print("Stopping A")                                                                                                                                                                                                                                                 

class B(AI):                                                                                                                                                                                                                                                                
    def stop(self):                                                                                                                                                                                                                                                         
        print("Stopping B")     
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37552237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档