1

クラスの特定のメソッドの定義を強制するのに役立つ次のコードを作成しました。

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

このようにして、メソッドが欠落している場合、呼び出し元のクラスは、必要なメソッドの定義に失敗したことを示す意味のあるエラーを生成します。

問題は、上記のコードが不快なほどハッキーで非 Pythonic であるように見えることです。私はこれを正しい方法で行っていますか?このようなクラス テンプレートを強制する必要がありますか? そして、同じことを達成するためのより良い方法はありますか?

4

4 に答える 4

4

ABCMeta次のメタクラスを使用できます。

from abc import ABCMeta, abstractmethod

class MyClass:
    __metaclass__ = ABCMeta

    @abstractmethod
    def foo(self):
        pass

インスタンス化できるようにするには、 のサブクラスをMyClassオーバーライドする必要があります。foo

于 2012-11-19T13:43:16.640 に答える
2

代わりにメタクラスを使用する必要があります。

標準ライブラリには、このタスク専用の既製のメタクラスである metaclass が付属していABCMetaます

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()
于 2012-11-19T13:43:30.750 に答える
0

Python 2.6+ を使用している場合、ABC の概念があります - http://docs.python.org/2/library/abc.html

于 2012-11-19T13:43:50.417 に答える
0

抽象基本クラスを再発明しようとしているようです

私はあなたがこのようなものが欲しいと思います:

import abc

class MyBaseClass:
    __metaclass__ = abc.ABCMeta
    @abc.abstractmethod
    def foo(self):
        pass

    @abc.abstractmethod
    def bar(self):
        pass

    @abc.abstractmethod
    def baz(self):
        pas
于 2012-11-19T13:46:55.053 に答える