Python中带有特定参数的抽象方法

7 投票
1 回答
6885 浏览
提问于 2025-04-17 23:27

我用abc包实现了一个抽象类。下面的程序没有任何问题。

有没有办法让它出错呢?因为抽象方法MyMethod是有一个参数a的,但在Derivative类中对' MyMethod'的实现却没有这个参数。所以我想不仅要在接口类Base中指定方法,还想指定这些方法的参数。

import abc

#Abstract class
class Base(object):
    __metaclass__  = abc.ABCMeta

    @abc.abstractmethod
    def MyMethod(self, a):
        'MyMethod prints a'


class Derivative(Base)

    def MyMethod(self):
        print 'MyMethod'

1 个回答

3

下面的代码是从一个代理类中复制过来的,它的工作方式类似。它会检查所有的方法是否都存在,并且这些方法的签名是否完全相同。这个检查的工作是在 _checkImplementation() 这个函数里完成的。注意那两行以 ourf 和 theirf 开头的代码;_getMethodDeclaration() 这个函数会把方法的签名转换成字符串。在这里,我选择要求这两个签名必须完全相同:

  @classmethod
  def _isDelegatableIdentifier(cls, methodName):
    return not (methodName.startswith('_') or methodName.startswith('proxy'))



  @classmethod
  def _getMethods(cls, aClass):
    names  = sorted(dir(aClass), key=str.lower)
    attrs  = [(n, getattr(aClass, n)) for n in names if cls._isDelegatableIdentifier(n)]
    return dict((n, a) for n, a in attrs if inspect.ismethod(a))



  @classmethod
  def _getMethodDeclaration(cls, aMethod):
    try:
      name = aMethod.__name__
      spec = inspect.getargspec(aMethod)
      args = inspect.formatargspec(spec.args, spec.varargs, spec.keywords, spec.defaults)
      return '%s%s' % (name, args)
    except TypeError, e:
      return '%s(cls, ...)' % (name)



  @classmethod    
  def _checkImplementation(cls, aImplementation):
    """
    the implementation must implement at least all methods of this proxy,
    unless the methods is private ('_xxxx()') or it is marked as a proxy-method
    ('proxyXxxxxx()'); also check signature (must be identical).
    @param aImplementation: implementing object
    """
    missing = {}

    ours   = cls._getMethods(cls)
    theirs = cls._getMethods(aImplementation)

    for name, method in ours.iteritems():
        if not (theirs.has_key(name)):
          missing[name + "()"] = "not implemented"
          continue


        ourf   = cls._getMethodDeclaration(method)
        theirf = cls._getMethodDeclaration(theirs[name])

        if not (ourf == theirf):
          missing[name + "()"] = "method signature differs"

    if not (len(missing) == 0):
      raise Exception('incompatible Implementation-implementation %s: %s' % (aImplementation.__class__.__name__, missing))

撰写回答