からコピーされたメタクラスのための可能な用途のように思えます。何にでもメタクラスを使用する必要はほとんどありません。ほとんどの場合、メタクラスは過度のものです。メタクラスを使用して達成できるほとんどのことは、デコレータを使用してより簡単に達成できます。ただし、このようにして、ベースハンドラのサブクラスが自動的に登録されるようにすることもできます(登録しないことを要求しない限り)。
class HandlerManager:
handlers = []
@classmethod
def register(cls, handler):
print("registering", handler)
cls.handlers.append(handler)
class HandlerRegisterer(type):
def __init__(self, name, bases, attrs, register=True):
super().__init__(name, bases, attrs)
if register:
HandlerManager.register(self)
def __new__(metaclass, name, bases, attrs, register=True):
return super().__new__(metaclass, name, bases, attrs)
class BaseHandler(metaclass=HandlerRegisterer, register=False):
# not actually a real handler, so don't register this class
pass
class MyHandler(BaseHandler):
# only have to inherit from another handler to make sure this class
# gets registered.
pass
print(HandlerManager.handlers)
assert BaseHandler not in HandlerManager.handlers
assert MyHandler in HandlerManager.handlers
あなたは抽象クラスを使用する必要がある場合、あなたはあなたのメタクラスのサブクラスABCMeta
を行う必要があります。これは、抽象クラスはメタクラスを使用することで実現され、Pythonではクラスに1つのメタクラスしか持たないためです。 ABCMetaをサブクラス化することによって、2つのサブクラスを互換性のあるものにできます。
from abc import ABC, ABCMeta, abstractmethod
class HandlerRegisterer(ABCMeta):
# subclass ABCMeta rather than type
def __init__(self, name, bases, attrs, register=True):
super().__init__(name, bases, attrs)
if register:
HandlerManager.register(self)
def __new__(metaclass, name, bases, attrs, register=True):
return super().__new__(metaclass, name, bases, attrs)
class AbstractSubHandler(MyHandler, ABC, register=False):
# not strictly necessary to subclass ABC, but nice to know it won't
# screw things up
@abstractmethod
def some_method(self):
pass
try:
AbstractSubHandler()
except TypeError:
print("Can not instantiate abstract class")
print(HandlerManager.handlers)
assert AbstractSubHandler not in HandlerManager.handlers
「読み込み」クラスは正確に何を意味していますか?小さな、自立した例を教えてください。 –