繁体   English   中英

我如何在 python 的 class 方法中注入代码?

[英]How i can to inject code in class method in python?

我如何在 class 方法中注入代码。我必须使用这么多方法(app_one app_two ...)。 我认为代码不是美,看起来像在多行中重复。 我想知道如何重构这段代码?

class Main:
     def step_one(self):
         print("STEP 1")

     def step_tree(self):
         print("STEP 3")
     
     def app_one(self):
         self.step_one()
         /// do_something
         self.step_two()

     def app_two(self):
         self.step_one()
         /// do_something
         self.step_two()

     def app_three(self):
         self.step_one()
         /// do_something
         self.step_two()

感谢专家。

我们可以定义一个装饰器,它接受一个普通的实例方法,并将它变成一个你想要的序言和尾声。 这是我们的装饰器的样子

def wrapped_app(fn):
    def wrapped_fn(self, *args, **kwargs):
        self.step_one()
        fn(self, *args, **kwargs)
        self.step_three()
    return wrapped_fn

因此,给定一个 function fnwrapped_app返回一个新的 function (我们在本地称为wrapped_fn ),它执行self.step_one() ,然后是fn ,然后self.step_three() 我们现在可以在 class 中使用装饰器语法

class Main:

    def step_one(self):
        print("STEP 1")

    def step_three(self):
        print("STEP 3")

    @wrapped_app
    def app_one(self):
        print("App one")

    @wrapped_app
    def app_two(self):
        print("App two")

    @wrapped_app
    def app_three(self):
        print("App three")

我们可以检查它是否工作如下

>>> main = Main()
>>> main.app_one()
STEP 1
App one
STEP 3

我们还可以更进一步 go 。 您当前的app_one等人不返回任何内容,但我们可能希望这些函数能够返回。 wrapped_fn稍作修改将处理这种可能性。 同样,我们可能还希望step_three保证运行,即使我们的应用程序 function 失败或引发异常。 我们可以使用try... finally来这样做。

def wrapped_app(fn):
    def wrapped_fn(self, *args, **kwargs):
        self.step_one()
        try:
            result = fn(self, *args, **kwargs)
        finally:
            self.step_three()
        return result
    return wrapped_fn

一种方法是使用装饰器:

from functools import wraps

def call_step_one_step_two(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        self.step_one()
        func(self, *args, **kwargs)
        self.step_two()
    return wrapper


class Main:
     def step_one(self):
        print("STEP 1")

     def step_two(self):
        print("STEP 3")

     @call_step_one_step_two
     def app_one(self):
        // do something

     @call_step_one_step_two
     def app_two(self):
        // do something

     @call_step_one_step_two
     def app_three(self):
        // do something

包装在这个装饰器中的所有方法总是在方法之前调用step_one ,在方法之后调用step_two 但是,这不支持返回值。 希望这已经足够了。

像这样的东西?

class Main:
     def step_one(self):
         print("STEP 1")

     def step_tree(self):
         print("STEP 3")
     
     def app_one_function(self):
         # do_something_app_one_unique

     def app_two_function(self):
         # do_something_app_two_unique

     def app_three_function(self):
         # do_something_app_three_unique

     def run_app(self, function):
         self.step_one()
         function()
         self.step_two()

或者你可以像这样使用装饰器

def decorator(function):
    def decorated(cls):
        cls.step_one()
        function(cls)
        cls.step_two()
    return decorated

class Main:
     def step_one(self):
         print("STEP 1")

     def step_tree(self):
         print("STEP 3")
     
     @decorator
     def app_one(self):
         # do_something_app_one_unique

     @decorator
     def app_two(self):
         # do_something_app_two_unique

     @decorator
     def app_three(self):
         # do_something_app_three_unique

obj = Main()
obj.app_one()
obj.app_two()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM