0

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?

askedJul 18, 2018 at 7:18
Hari's user avatar
7
  • fyi, what you are talking about is not a metaclass but a baseclass.Metaclass has a very specific meaning and refers to something completely different.CommentedJul 18, 2018 at 7:34
  • We can also usemetaclass to achieve this right?CommentedJul 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.CommentedJul 18, 2018 at 7:58
  • 1
    That looks interesting, I'll try to have a look and get back if it turns out that I misunderstood your question.CommentedJul 18, 2018 at 8:28
  • 1
    Note that you could implement__init_subclass__ to verify assertions about a child without defining a metaclass.CommentedJul 20, 2018 at 23:18

1 Answer1

2

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 bar

Another 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 NotImplementedError
answeredJul 18, 2018 at 7:27
Thtu's user avatar
Sign up to request clarification or add additional context in comments.

2 Comments

I want to enforce constraint forderived class without implementingbar method in myBase class, and i am confused about example 1, i think it enforcefoo right? but i need to enforcebar()
To enforcebar for a derived class, declare an abstract method on your base class for that method. Edited response to reflect this.

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.