我正在尝试将一个“子命令”系统实现为Python中的可继承类。我的预期用例类似于:
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显然不起作用:
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
装饰器,然后在类定义完成后将其注入。
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的人,这对我来说非常笨重。有没有更优雅的方法来实现这一目标?
答案 0 :(得分:5)
我能想到这个问题有两个解决方案。最简单的方法是在完成后在父类中使用它,使其成为静态方法:
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.
这有点脆弱,因为在将它作为静态方法后,不能在父类中使用它。更强大的方法是添加一个中间类:
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
继承所有课程。