45

I have this example code, with a class B nested inside class A:

class A:
    class B:
        count = 0
        def __init__(self,b1=None,b2=None):
            self.b1 = b1
            self.b2 = b2
        def funcb(self,bb):
            A.a1 = pyfunc1(bb)
    def __init__(self,a1,a2):
        self.a1 = a1
        self.a2 = a2
        self.listb = [A.B()]
    def funca(self,aa):
        A.B.count += 1
        b = A.B(self.a1,self.a2)
        listb.append(b)
        listb[A.B.count].b1 = listb[A.B.count-1].b1.pyfunc2(aa)
        listb[A.B.count].b2 = pyfunc3(aa,self.a2)
        listb[A.B.count].funcb(self.a2)

Here, the A class maintains a list of instances of the nested B class. B provides functionality to change A's other instance variable a1, while A has a function to change B's instance variable bb. Which is to say, these classes can access each other.

Will nesting classes like this reduce the efficiency of the code? How else can I solve the problem?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
xibinke
  • 865
  • 2
  • 9
  • 11
  • 1
    You might want to read [the zen](https://www.python.org/dev/peps/pep-0020/). – Ami Tavory May 21 '15 at 14:08
  • 1
    Python's nested classes aren't like Java's where the nested class where the inner class can reference instances of the outer class. They're effectively two separate classes. `A.a1 = pyfunc1()` will assign the `a1` field on the _class_. – Colonel Thirty Two May 21 '15 at 14:08
  • I tried to fix the question to make it more objective and easier to understand. However, the example still does not make any sense. Contrary to the assertion, `B` **does not** have a way to modify the `a1` attribute ("instance variable" is not real terminology) of `A` instances; it instead assigns `a1` **on the `A` class itself**. Further, there are several functions not defined here and it isn't at all clear what they're intended to represent or why they should be important to the example. Finally, making classes maintain a count of their instances is a debugging nightmare. – Karl Knechtel Feb 11 '23 at 17:54

1 Answers1

85

Nesting a class doesn't reduce nor increase execution efficiency. It may alter maintenance and understanding efficiency.

The nested class becomes just another attribute on the parent class. You'll have to reference it as A.B rather than B. That's it, you deferred the lookup to a different namespace. In other words, your __init__ method will fail, because there is no global name B, only A.B and self.B exist (both referencing the same class object).

There is otherwise no special relationship between a nested class and their parent, as there is in Java.

Most Python developers do not nest classes, so when you do so you break convention and increase maintenance cost.

Mike B
  • 627
  • 3
  • 11
  • 19
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    Thank you. I modified my script according to you suggestion. And I'll give up such kind of style hence. – xibinke May 21 '15 at 14:20
  • How about nesting Enums? Is it ok if this enum will be used only inside the class itself? – Peter Aug 07 '22 at 03:47
  • @Peter: So? Then just give the enum a name starting with an underscore, or don't make it part of the exported API of the package (if you are using a python package), etc. There is no advantage to nesting the Enum inside your class, only disadvantages. – Martijn Pieters Aug 11 '22 at 21:03