Sinan Cetinkaya
Sinan Cetinkaya

Reputation: 457

calling parent's method with parameter from nested class in python

class Parent(object):
    def __init__(self):
        self.text = "abc"
        self.child = self.Child()

    def run(self):
        self.child.task()

    def output(self, param1):
        print(param1)

    class Child(object):
        def __init__(self):
            self.text = "cde"

        def task(self):
            Parent.output(Parent, self.text)  # I get the warning for this line


parent = Parent()
parent.run()

Code above works as expected but IntelliJ IDEA is warning me with this message "An instance of nested_classes.Parent expected, not the class itself" Is there something wrong with my code? Thanks!

Upvotes: 2

Views: 708

Answers (2)

idjaw
idjaw

Reputation: 26578

You are trying to access your output method (which is an instance method) as a class method. The message is coming up because the first parameter self is the instance object, so you passing the class as the first parameter will actually change the content of what self should have as an instance object. That is what the message is trying to tell you. So, what you actually should be doing is call the method as an instance method:

Parent().output(self.text)

Based on what you were doing, if you check the repr and contents of the object of self inside the output method, you get this:

def output(self, param1):
    print(repr(self))
    print(dir(self))
    print(param1)

Using this method of calling: Parent.output(Parent, self.text)

<class '__main__.Parent'>
[
    'Child', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', 
    '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
    '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', 
    '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', 
    '__subclasshook__', '__weakref__', 'output', 'run'
]

As you can see, you do not have an instance of Parent in your self.

Now, if you call it as an instance method: Parent().output(self.text)

<__main__.Parent object at 0x1021c6320>
[
    'Child', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
    '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', 
    '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', 
    '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
    '__weakref__', 'child', 'output', 'run', 'text'
]

As you can see, you now have a Parent object and if you look at the contents of the object, you would have what you would expect from your instance properties.

Upvotes: 3

John Chang
John Chang

Reputation: 131

You did not declare output as a class method so it expects to be called by an instance of Parent.

Upvotes: 1

Related Questions