More precisely, I would like to remove the line self.B = B in the code below.
class A:
def __init__(self, x):
class B:
def __init__(self):
self.x = x
self.B = B
>Solution :
From what I understand, you want to create a class in A.__init__ which is directly stored into an instance variable, without first creating a local variable and then assigning that to an instance variable afterwards.
Unfortunately, there’s no way to do this if you use the class keyword to create the class, because it will always put the created class in the current scope (as a local variable of A.__init__).
However, you can technically do this by creating the class dynamically instead, using the three-argument type function. I would probably not recommend this though, as it’s way less readable.
class A:
def __init__(self, x):
self.B = type("B", (), {"__init__": lambda self: setattr(self, "x", x)})
This will also let you specify the name of the class. You could just use "B", as in the example above, or you could use "A().B" or f"A({x}).B" or f"{repr(self)}.B" or something to make it clearer that B is part of an instance of A.
Here is a quote from the documentation explaining what is going on:
type(name, bases, dict, **kwds)With three arguments, return a new type object. This is essentially a dynamic form of the class statement. The name string is the class name and becomes the
__name__attribute. The bases tuple contains the base classes and becomes the__bases__attribute; if empty, object, the ultimate base of all classes, is added. The dict dictionary contains attribute and method definitions for the class body; it may be copied or wrapped before becoming the__dict__attribute.