当前位置: 首页 > 面试题库 >

具有可装饰方法或函数的参数的基于Python类的装饰器

夹谷硕
2023-03-14
问题内容

我已经看到许多Python装饰器的示例,它们是:

  • 函数样式修饰符(包装函数)
  • 类风格装饰(实施__init____get____call__
  • 不带参数的装饰器
  • 带参数的装饰器
  • “方法友好”的装饰器(即可以装饰类中的方法)
  • “功能友好”的装饰器(可以装饰普通功能
  • 可以装饰方法和功能的装饰器

但是我从未见过一个可以完成上述所有操作的示例,而且我无法从各种答案到特定问题,这个或这个上看到过,如何结合以上所有内容。

我想要的是一个 _ 基于类的 装饰器,它可以装饰 _ 一个方法或一个函数 ,并且 _ 至少需要一个附加参数_。即,以便以下工作:

class MyDecorator(object):
    def __init__(self, fn, argument):
        self.fn = fn
        self.arg = argument

    def __get__(self, ....):
        # voodoo magic for handling distinction between method and function here

    def __call__(self, *args, *kwargs):
        print "In my decorator before call, with arg %s" % self.arg
        self.fn(*args, **kwargs)
        print "In my decorator after call, with arg %s" % self.arg


class Foo(object):
    @MyDecorator("foo baby!")
    def bar(self):
        print "in bar!"


@MyDecorator("some other func!")
def some_other_function():
    print "in some other function!"

some_other_function()
Foo().bar()

我希望看到:

In my decorator before call, with arg some other func!
in some other function!
In my decorator after call, with arg some other func!
In my decorator before call, with arg foo baby!
in bar!
In my decorator after call, with arg foo baby!

编辑:如果有关系,我正在使用Python 2.7。


问题答案:

您不需要弄乱描述符。在__call__()方法内部创建包装函数并返回它就足够了。根据上下文,标准Python函数始终可以充当方法或函数

class MyDecorator(object):
    def __init__(self, argument):
        self.arg = argument

    def __call__(self, fn):
        @functools.wraps(fn)
        def decorated(*args, **kwargs):
            print "In my decorator before call, with arg %s" % self.arg
            fn(*args, **kwargs)
            print "In my decorator after call, with arg %s" % self.arg
        return decorated

关于使用这种装饰器时发生的情况的一些解释:

@MyDecorator("some other func!")
def some_other_function():
    print "in some other function!"

第一行创建的实例MyDecorator并将其"some other func!"作为参数传递给__init__()。我们称这个实例my_decorator。接下来,创建未修饰的函数对象(我们称其为“对象”)bare_func并将其传递给装饰器实例,然后my_decorator(bare_func)执行该对象。这将调用MyDecorator.__call__(),这将创建并返回包装器函数。最后,将此包装函数分配给名称some_other_function



 类似资料:
  • 本文向大家介绍基于Python 装饰器装饰类中的方法实例,包括了基于Python 装饰器装饰类中的方法实例的使用技巧和注意事项,需要的朋友参考一下 title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] category: ['Python'] --- 目前在中文网

  • 问题内容: 我在装饰器传递变量时遇到问题。我可以通过以下装饰器语句来做到这一点: 但不幸的是,该声明不起作用。也许也许有更好的方法来解决此问题。 问题答案: 带参数的装饰器的语法有些不同-带参数的装饰器应返回一个函数,该函数将接受一个函数并返回另一个函数。因此,它实际上应该返回一个普通的装饰器。有点混乱吧?我的意思是: 在这里,你可以阅读有关该主题的更多信息-也可以使用可调用对象来实现此目的,这也

  • 主要内容:带参数的函数装饰器,函数装饰器可以嵌套前面章节中,我们已经讲解了 Python 内置的 3 种函数装饰器,分别是 @staticmethod、@classmethod 和 @property,其中 staticmethod()、classmethod() 和 property() 都是 Python 的内置函数。 那么,函数装饰器的工作原理是怎样的呢?假设用 funA() 函数装饰器去装饰 funB() 函数,如下所示: 实际上,上面

  • 本文向大家介绍python通过装饰器检查函数参数数据类型的方法,包括了python通过装饰器检查函数参数数据类型的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了python通过装饰器检查函数参数数据类型的方法。分享给大家供大家参考。具体分析如下: 这段代码定义了一个python装饰器,通过此装饰器可以用来检查指定函数的参数是否是指定的类型,在定义函数时加入此装饰器可以非常清晰的检测函

  • 问题内容: 我想这就是它们的称呼,但我会举一些例子以防万一。 装饰类: 装饰器功能: 使用一个或另一个只是口味的问题吗?有实际区别吗? 问题答案: 如果您可以编写函数来实现装饰器,则应首选它。但是并非所有装饰器都可以轻松地编写为一个函数-例如,当您要存储一些内部状态时。 我见过人们(包括我自己)经过荒唐的努力,只用函数编写装饰器。我仍然不知道为什么,一个班级的开销通常可以忽略不计。

  • 问题 你想写一个装饰器,既可以不传参数给它,比如 @decorator , 也可以传递可选参数给它,比如 @decorator(x,y,z) 。 解决方案 下面是9.5小节中日志装饰器的一个修改版本: from functools import wraps, partial import logging def logged(func=None, *, level=logging.DEBUG,