I am trying to learnmetaclasses in python, from my research i found a example like follow.
i have aBase andDerived classes like follow
class Base(): def foo(self): return self.bar() class Derived(Base): def foo2(self): return "i am foo2"now, when i want to make sure that whoever extendingBase class, must need to implementbar() method, so i created the meta class to hook the constuction of derived class,so nowBase class looks like follow withBaseMeta meta class.
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()The problem is when i get looks into body it returns 2 records forBase andDerived class, like follow.
{'__module__': '__main__', '__qualname__': 'Base', 'foo': <function Base.foo at 0x7ffbaae436a8>} {'__module__': '__main__', '__qualname__': 'Derived', 'bar': <function Derived.bar at 0x7ffbaae437b8>}my code in__new__ breaks sinceBase not havebar, but i want to check only in the Derived class so i rewrite mymetaclass like follow.
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)I am checkingname != Base in my__new__ method.
Is that the right way to do it or we can use some other best way?
- We can also use
metaclassto achieve this right?Hari– Hari2018-07-18 07:40:03 +00:00CommentedJul 18, 2018 at 7:40 - Theoretically, I am sure. But metaclasses are intended to achieve something different calledclass alteration. Sorry that I am so vague, but I don't understand their use very well myself and just trust the top-voted answer from the question I linked which says that99% of the time you need class alteration, you are better off using [monkey patching or decorators]. But 98% of the time, you don't need class alteration at all and go about my day ignoring that metaclasses exist.Arne– Arne2018-07-18 07:58:01 +00:00CommentedJul 18, 2018 at 7:58
- 1That looks interesting, I'll try to have a look and get back if it turns out that I misunderstood your question.Arne– Arne2018-07-18 08:28:02 +00:00CommentedJul 18, 2018 at 8:28
- 1Note that you could implement
__init_subclass__to verify assertions about a child without defining a metaclass.chepner– chepner2018-07-20 23:18:06 +00:00CommentedJul 20, 2018 at 23:18
1 Answer1
You can use theabc module in the stdlib, which has tools for doing exactly this.https://docs.python.org/3/library/abc.html
import abcclass Base(abc.ABC): @abc.abstractmethod def bar(self): passclass Derived(Base): pass# This will raise an error because foo is not implemented# >>> Derived() # TypeError: Can't instantiate abstract class Derived with abstract methods barAnother strategy would be to have abar method on your Base class that raises a NotImplementedError. The main difference is that no error is raised until you actually call something that requiresbar. e.g.
class Base(): def foo(self): return self.bar() def bar(self): raise NotImplementedError2 Comments
derived class without implementingbar method in myBase class, and i am confused about example 1, i think it enforcefoo right? but i need to enforcebar()bar for a derived class, declare an abstract method on your base class for that method. Edited response to reflect this.Explore related questions
See similar questions with these tags.

