【问题标题】:Class method as a decorator类方法作为装饰器
【发布时间】:2014-02-18 09:44:53
【问题描述】:

我有一个类,我有多种方法。我想将其中一种方法用作其他方法的装饰器。为此,我使用以下语法:

@self.action
def execute(self,req):    

action 是我课堂上的其他方法。但它不起作用并抛出异常为

name 'self' is not defined

【问题讨论】:

  • 目前,当函数创建和装饰时,实例(甚至类)还不存在,所以你不能那样做。可以做什么,取决于action 应该做什么。
  • action 是一个基类方法。有许多派生类,每个派生类都有一个执行特定操作的方法。在每个操作之前和之后,我都需要做一些我在基类方法中编写的操作。但是在每个派生类中,我都必须重复该代码。因此,我在基类中创建了一个名为 action 的方法,它将充当装饰器。
  • @gliese581g:装饰器是否需要知道该方法是在哪个类上定义的?
  • @gliese581g:那为什么要让它成为课程的一部分完全
  • @gliese581g:只需将其作为Base 类的next 函数,并将其与Base 一起导入即可。给它一个前导的下划线名称,这样from module import * 就不会包含它,任何值得一提的 Python 开发人员都会将其识别为私有实用程序函数。

标签: python decorator python-decorators


【解决方案1】:

在定义类时不能使用类的方法;类中没有self,也没有“烘焙”类甚至访问任何类。

您可以将方法视为函数以用作装饰器:

class SomeClass():
    def action(func):
        # decorate
        return wrapper

    @action
    def execute(self, req):
        # something

如果action 定义在基类上,那么您必须通过基类引用名称:

class Base():
    @staticmethod
    def action(func):
        # decorate
        return wrapper

class Derived(Base):
    @Base.action
    def execute(self, req):
        # something

对于 Python 2,您必须在此处将 action 设为静态方法,否则您会得到一个未绑定的方法,该方法会抱怨您不能在没有实例作为第一个参数的情况下调用它。在 Python 3 中,您可以在此处省略 @staticmethod 装饰器,至少对于装饰器而言是这样。

但请注意action 不能直接用作方法;也许那时它根本不应该成为课程的一部分。它不是这里的最终用户 API 的一部分,可能这些类的实例的消费者不使用装饰器。

【讨论】:

  • 回避 action 是否应该是类的一部分的问题,action 可以定义为静态方法 (@staticmethod def action(func)...)。
  • @chepner:当然,但这并没有使静态方法变得更有用。
  • 如果我们想在action中调用SomeClass的另一个方法怎么办?我们无法使用self. 访问SomeClass 实例的方法和属性
【解决方案2】:

在python中,“self”作为参数(第一个)传递给实例方法,“self”只是一个约定,可以称它为“foobarbaz”(当然这很愚蠢)......重点是,从外部看,“self”没有定义(因为它的作用域是方法)……你不能用其他类方法装饰类方法,而是必须编写一个单独的类!

【讨论】:

    猜你喜欢
    • 2016-10-14
    • 2014-01-14
    • 2021-04-12
    • 2020-01-11
    • 2015-03-17
    • 2017-07-28
    • 1970-01-01
    • 2019-02-20
    • 2012-09-11
    相关资源
    最近更新 更多