0

The below code works fine where I'm creating objects for Outer and inner classes individually and passing the arguments

class Student:
    def __init__(self,name,rollno):
        self.name = name
        self.rollno = rollno
    def show(self):
        print(self.name,self.rollno)
        #self.lap.show()

    class Laptop: #inner class
        def __init__(self,brand,cpu'):
            self.brand = brand
            self.cpu = cpu
        def show(self):
            print(self.brand,self.cpu)
s1 = Student('Ram',21)
lap1 =s1.Laptop('Dell','i3')
lap1.show()

In the second code, I have created the inner class(Laptop) object inside the Outer(Student) class. In that case, how can we pass the arguments to the inner class?

class Student:
    def __init__(self,name,rollno):
        self.name = name
        self.rollno = rollno
        self.lap = self.Laptop()  #lap is the obj of a inner class

    def show(self):
        print(self.name,self.rollno)
        self.lap.show()  

I tried with self.lap = self.Laptop(brand,cpu), assigning parameters and passing the arguments in differnet ways, but none worked for me. Is there any way where I can pass the arguments?

  • 3
    This sounds kind of like you're expecting Java behavior. Defining a class inside another class in Python is mostly just awkward. It doesn't do the stuff that Java inner classes do. – user2357112 Jan 05 '22 at 09:52
  • 2
    If you want the `Student` initialiser to create a `Laptop` object then you need to give it the values to pass to the `Laptop` initialiser. For example, you could define it as `__init__(self, name, rollno, brand, cpu)` and pass the latter two when creating the `Laptop`. My preference would be to create the laptop object in the calling code and pass that to the student object, but it depends on how you're going to use it. – Kemp Jan 05 '22 at 09:52
  • 1
    In this case.. how about separate two class? you can make laptop instance from Laptop class and set laptop attribute in Student instance using laptop instance. – SEUNGFWANI Jan 05 '22 at 09:53

2 Answers2

5

I don't really see the added benefit of the inner class. I've seen few usecases where they actually contribute to the readability of the code. In your code I would suggest to simply use two 'top level' classes. Only in some complex cases do inner classes really help.

class Student:
    def __init__(self, name, rollno, laptop=None):
        self.name = name
        self.rollno = rollno
        self.laptop = laptop

    def show(self):
        print(self.name, self.rollno)
        if self.laptop:
            self.laptop.show()

class Laptop:
    def __init__(self, brand, cpu):
        self.brand = brand
        self.cpu = cpu

    def show(self):
        print(self.brand, self.cpu)

And then in usage, simply initialize and pass them on as needed:

lap1 = Laptop('Dell', 'i3')
s1 = Student('Ram', 21, lap1)
lap1.show()
s1.show()
s2 = Student('Stackoverflow', 9999, lap1)
s2.show()
s3 = Student('No laptop', 2)
s3.show()
The Pjot
  • 1,801
  • 1
  • 12
  • 20
2

If you really want Laptop class to be contained in Student class, either pass arguments to Student constructor or replace self.lap = self.Laptop() with self.lap = None. That way you don't need to worry about those arguments at the time of creating student and can later assign the Laptop to the Student like in the first example.

class Student:
    def __init__(self,name,rollno):
        self.name = name
        self.rollno = rollno
        self.lap = None  #lap is the obj of a inner class

    def show(self):
        print(self.name,self.rollno)
        self.lap.show() 

    class Laptop: #inner class
        def __init__(self,brand,cpu):
            self.brand = brand
            self.cpu = cpu
        def show(self):
            print(self.brand,self.cpu)

s1 = Student('Ram',21)
lap1 =s1.Laptop('Dell','i3')
lap1.show()
matszwecja
  • 6,357
  • 2
  • 10
  • 17