首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在类中定义装饰器,这在类定义中也是有用的

在类中定义装饰器,这在类定义中也是有用的
EN

Stack Overflow用户
提问于 2011-01-31 05:20:07
回答 1查看 879关注 0票数 5

我正在尝试在Python中实现一个“子命令”系统作为一个可继承的类。我的预期用例类似于:

代码语言:javascript
复制
from command import Command
import sys

class MyCommand(Command):
    @Command.subcommand
    def foo(self):
        print "this can be run as a subcommand"

    def bar(self):
        print "but this is a plain method and isn't exposed to the CLI"

MyCommand()(*sys.argv)

# at the command line, the user runs "mycommand.py foo"

我将Command.subcommand实现为一个静态方法,一切都运行得很好,直到我尝试向父类添加子命令,这使我获得了TypeError: 'staticmethod' object is not callable。事后看来,很明显,this不会工作:

代码语言:javascript
复制
class Command(object):
    @staticmethod
    def subcommand(method):
        method.is_subcommand = True

        return method

    @subcommand
    def common(self):
        print "this subcommand is available to all child classes"

到目前为止,我找到的唯一替代方法是在父类外部声明subcommand装饰器,然后在类定义完成后注入它。

代码语言:javascript
复制
def subcommand(method):
    method.is_subcommand = True

    return method

class Command(object):
    @subcommand
    def common(self):
        print "this subcommand is available to all child classes"

Command.subcommand = staticmethod(subcommand)
del subcommand

然而,作为一个在添加装饰器之前从未使用过Python的人,这对我来说感觉非常笨拙。有没有更优雅的方式来实现这一点呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-01-31 05:38:27

对于这个问题,我能想到两种解决方案。最简单的方法是在父类中使用完之后,将它变成一个静态方法

代码语言:javascript
复制
class Command(object):
    def subcommand(method): # Regular function in class definition scope.
        method.is_subcommand = True

        return method

    @subcommand
    def common(self):
        print "this subcommand is available to all child classes"

    subcommand = staticmethod(subcommand)
    # Now a static method. Can no longer be called during class definition phase.

这有点脆弱,因为在将其设置为静态方法之后,您不能在父类中使用它。更健壮的方法是添加一个中间类:

代码语言:javascript
复制
class Command(object):
    @staticmethod
    def subcommand(method):
        method.is_subcommand = True

        return method

class CommandBase(Command):

    @Command.subcommand
    def common(self):
        print "this subcommand is available to all child classes"

现在,您可以从CommandBase而不是Command继承所有类。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4845613

复制
相关文章

相似问题

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