-2

Two notable ways to create a class are shown below:

class Klass:
    pass

Klass = type("Klass", tuple(), dict())

I would like to override the constructor (__call__) while still using the class keyword instead of doing something else, like directly calling type. I really do want to override (__call__), not __init__

My failed attempts are shown below:

Attempt 1

class Foo:
    @classmethod
    def __call__(*args):
        print("arr har")
        return super(type(args[0]), args[0]).__call__(*args)

instance = Foo()
# did not print "arr har"

Attempt 2

class BarMeta(type):
    def __call__(*args):
        print("hello world")
        return super(type(args[0]), args[0]).__call__(*args[1:])
  • Attempt 2A

    class Bar:
        __metaclass__ = BarMeta
    
    instance = Bar()
    # did not print "hello world" 
    
  • Attempt 2B

    Baz = BarMeta("Baz", tuple(), dict())
    instance = Baz()
    # Did print "hello world," but we weren't able to use the `class` keyword to create `Baz`
    
8
  • But __call__ is not he constructor, __new__ is. If you want to override __call__ all you have to do is override __call__ Commented Oct 27, 2019 at 12:06
  • Attempt 2A would work if you were using python 2. In python 3, the syntax for defining a metaclass is class Bar(metaclass=BarMeta):. Commented Oct 27, 2019 at 12:08
  • @DeepSpace But __call__ calls __new__, not the other way around. instance = Klass() is the same as instance = Klass.__call__() or instance = type(Klass).__call__(Klass) Commented Oct 27, 2019 at 12:09
  • Also, I (and apparently at least 2 other people) had a hard time understanding your question. It would've been a good idea to start by explicitly stating what you want to do, i.e. "I want Bar() to print 'arr har'". Commented Oct 27, 2019 at 12:10
  • 1
    @DeepSpace type.__call__ is really the only example. repl.it/repls/EvenSandyPress Commented Oct 27, 2019 at 13:03

1 Answer 1

0

All credit does to Aran-Fey, who posted the answer as a comment, instead of as an answer:

class BarMeta(type):
    def __call__(*args):
        print("hello world")
        return super(type(args[0]), args[0]).__call__(*args[1:])    

class Bar(metaclass=BarMeta):
    pass

instance = Bar()
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.