我正尝试在python中学习metaclasses
,根据研究发现,我发现了以下示例。
我有一个Base
和Derived
类,例如follow
class Base():
def foo(self):
return self.bar()
class Derived(Base):
def foo2(self):
return "i am foo2"
现在,当我要确保扩展Base
类的任何人都必须实现bar()
方法时,我创建了元类来挂钩派生类的构造,所以现在{{ 1}}类看起来像跟着Base
元类。
BaseMeta
问题是当我查看正文时,它会返回class BaseMeta(type):
def __new__(cls, name, bases, body):
if not "bar" in body:
raise TypeError("bar not implemented")
return super().__new__(cls, name, bases, body)
class Base(metaclass=BaseMeta):
def foo(self):
return self.bar()
和Base
类的2条记录,如下所示。
Derived
由于 {'__module__': '__main__', '__qualname__': 'Base', 'foo': <function
Base.foo at 0x7ffbaae436a8>}
{'__module__': '__main__', '__qualname__': 'Derived', 'bar': <function
Derived.bar at 0x7ffbaae437b8>}
没有__new__
,所以Base
中的代码中断了,但是我只想检查Derived类,所以我像下面那样重写了bar
。>
metaclass
我正在用def __new__(cls, name, bases, body):
if name !="Base" and not "bar" in body:
raise TypeError("bar not implemented")
return super().__new__(cls, name, bases, body)
方法检查name != Base
。
是正确的方法还是我们可以使用其他最佳方法?
答案 0 :(得分:2)
您可以使用stdlib中的abc
模块,该模块具有执行此操作的工具。
https://docs.python.org/3/library/abc.html
import abc
class Base(abc.ABC):
@abc.abstractmethod
def bar(self):
pass
class Derived(Base):
pass
# This will raise an error because foo is not implemented
# >>> Derived()
# TypeError: Can't instantiate abstract class Derived with abstract methods bar
另一种策略是在您的基类上使用一个bar
方法,该方法会引发NotImplementedError。主要区别在于,除非您实际调用需要bar
的东西,否则不会引发错误。例如
class Base():
def foo(self):
return self.bar()
def bar(self):
raise NotImplementedError