类Python中的装饰器

2024-05-14 10:43:43 发布

您现在位置:Python中文网/ 问答频道 /正文

对不起我的英语。我想创建一个decorator方法,它可以检查每个step方法并将其编写为db。在

这是我的方法:

class Test:

    @StepStatusManager.logger_steps("GET_LIST") # TypeError: logger_steps() missing 1 required positional argument: 'type'
    def get_mails(self):
       print("GET_MAIL")    

这是我的装饰课:

^{pr2}$

Tags: 方法testdbgetsteprequireddecoratorsteps
1条回答
网友
1楼 · 发布于 2024-05-14 10:43:43

您试图直接从类StepStatusManager调用实例方法logger_steps,而Python将值"GET_LIST"作为self参数,而不是{}。您应该创建一个StepStatusManager的实例,然后让decorator调用该实例的方法。它可以简单到:

manager = StepStatusManager()

class Test:
    @manager.logger_steps("GET_LIST")
    def get_mails(self):
       print("GET_MAIL")

这是在创建类的实例,然后在实例上调用方法,而不是直接从类调用方法。现在可以使用manager来修饰任意多个方法。另外,这将使所有修饰的方法使用相同的StepStatusManager,但如果您愿意,您可以创建不同的实例并使用它们来修饰不同的方法;这将允许您在需要时为不同的方法使用不同的self.db。在

另一种方法是在类中使用db变量,并将logger_steps改为class method

^{pr2}$

但是请注意,这是不够灵活的,因为它不允许您使用不同的管理器装饰方法,如果您需要的话。另外,这通常相当于使用StepStatusManager模块,其中db是模块变量,logger_steps是模块函数,如果您想要这个功能,这可能会更清楚:

# StepStatusManager.py

# ...

db = DB()

def logger_steps(type):
    def logger_steps(func):
        @functools.wraps(func)
        def wrapper(*args):
            try:
                func(*args)
                cls.db.setStatus(type)
            except BaseException as e:
                print(e)

        return wrapper

    return logger_steps

# test.py

import StepStatusManager

class Test:
    @StepStatusManager.logger_steps("GET_LIST")
    def get_mails(self):
       print("GET_MAIL")

同样,这可能更直接,但不如第一个建议的基于类的解决方案灵活。在


编辑:

为了完整性和比较性,这里还有另一个版本,类似于带有^{}的版本,但是使用了^{}(要了解这两个装饰器之间的细微差别,请检查其中一个关于它的问题,例如What is the difference between @staticmethod and @classmethod?Meaning of @classmethod and @staticmethod for beginner?):

class StepStatusManager:

    db = DB()

    @staticmethod
    def logger_steps(type):
        def logger_steps(func):
            @functools.wraps(func)
            def wrapper(*args):
                try:
                    func(*args)
                    StepStatusManager.db.setStatus(type)
                except BaseException as e:
                    print(e)

            return wrapper

        return logger_steps

class Test:
    @StepStatusManager.logger_steps("GET_LIST")
    def get_mails(self):
       print("GET_MAIL")

由于它经常发生在@classmethod和{}之间,所以差别非常小。如果使用继承,或者使用元类、decorator或诸如此类的东西,它们的行为可能会有所不同,但在其他方面它们几乎相同。在

相关问题 更多 >

    热门问题