强制类的方法定义

2024-06-07 14:43:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写了以下代码来帮助强制类的某些方法的定义:

def createClassTemplate(name, requiredMethods=[], inherits=object):
    def require(name):
        def errorRaiser(self, *args, **kwargs):
            raise RequireException("method '{}' must be defined.".format(name))
        setattr(wrapper, "__name__", name)
        return errorRaiser

    class Custom(inherits): pass

    setattr(Custom, "__name__", name)
    for methodName in requiredMethods:
        setattr(Custom, methodName, require(methodName))

    return Custom

实现方式如下:

Model = createClassTemplate("Model", ["foo", "bar", "baz"])

class MyClass(Model):
    pass

这样,当我缺少一个方法时,调用类将生成一个有意义的错误,表明我未能定义所需的方法。你知道吗

问题是,上面的代码似乎令人不安的黑客和不和谐。我走这条路对吗?我应该这样强制类模板吗?有没有更好的方法来完成同样的事情?你知道吗


Tags: 方法代码namemodelreturn定义defcustom
3条回答

可以使用^{}元类:

from abc import ABCMeta, abstractmethod

class MyClass:
    __metaclass__ = ABCMeta

    @abstractmethod
    def foo(self):
        pass

MyClass的子类必须重写foo才能被实例化。你知道吗

如果您使用的是python2.6+,那么就有一个ABC-http://docs.python.org/2/library/abc.html的概念

您应该改用metaclass。你知道吗

标准库为这个任务提供了一个现成的元类^{} metaclass

import abc

class Model(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def foo(self):
        pass

    @abc.abstractmethod
    def bar(self):
        pass

    @abc.abstractmethod
    def baz(self):
        pass

class MyClass(Model):
    pass

演示:

>>> import abc
>>> class Model(object):
...     __metaclass__ = abc.ABCMeta
...     @abc.abstractmethod
...     def foo(self):
...         pass
...     @abc.abstractmethod
...     def bar(self):
...         pass
...     @abc.abstractmethod
...     def baz(self):
...         pass
... 
>>> class MyClass(Model):
...     pass
... 
>>> myclass = MyClass()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class MyClass with abstract methods bar, baz, foo

一旦MyClass提供了抽象方法的实现,实例化就成功了:

>>> class MyClass(Model):
...     def foo(self): pass
...     def bar(self): pass
...     def baz(self): pass
... 
>>> myclass = MyClass()

相关问题 更多 >

    热门问题