Seriously: you really don't want to do this.
But, it is useful for experienced Python users to understand this, so I will explain it.
Cells and freevars are the values โโassigned when creating the closure. For example,
def f(): a = 1 def func(): print(a) return func
f returns a closure based on func , keeping a reference to a . This link is stored in the cell (actually in freevar, but which corresponds to the implementation). You can check this out:
myfunc = f()
("cells" and "freevars" are very similar. Freevars have names where the cells have indexes. Both of them are stored in func.__closure__ , and the cells go first. Here we only care about freevars , since there are __class__ .)
Once you understand this, you can see how super () works. Any function that contains a super call is actually a closure, with freevar named __class__ (which is also added if you reference __class__ yourself):
class foo: def bar(self): print(__class__)
(Warning: this is where things get evil.)
These cells are visible in func.__closure__ , but read-only; you cannot change it. The only way to change it is to create a new function that is executed using the types.FunctionType constructor. However, your __init__ function does not have __class__ freevar __class__ all - so we need to add it. This means that we also need to create a new code object.
Below is the code. I added base class B for demo purposes. This code makes some assumptions, for example. that __init__ no longer has a free variable named __class__ .
There is another hack: there is no constructor for the cell type. To get around this, a dummy C.dummy function is C.dummy that has the required cell variable.
import types class B(object): def __init__(self): print("base") class C(B): def dummy(self): __class__ def __init__(self): print('calling __init__') super().__init__() def MakeCodeObjectWithClass(c): """ Return a copy of the code object c, with __class__ added to the end of co_freevars. """ return types.CodeType(c.co_argcount, c.co_kwonlyargcount, c.co_nlocals, c.co_stacksize, c.co_flags, c.co_code, c.co_consts, c.co_names, c.co_varnames, c.co_filename, c.co_name, c.co_firstlineno, c.co_lnotab, c.co_freevars + ('__class__',), c.co_cellvars) new_code = MakeCodeObjectWithClass(__init__.__code__) old_closure = __init__.__closure__ or () C.__init__ = types.FunctionType(new_code, globals(), __init__.__name__, __init__.__defaults__, old_closure + (C.dummy.__closure__[0],)) if __name__ == '__main__': c = C()