0

I would like to understand Python classes and objects.

I am trying and struggling to get the output results from inner-class, Features.

class Person:
    def __init__(self):
        pass

    def first_name(self, first_name ):
        self.first_name = first_name
        return self.first_name

    def middle_name(self, middle_name):
        self.middle_name = middle_name

    def last_name(self, last_name):
        self.last_name = last_name
        return self.last_name

    class Features:
        def __init__(self):
            pass
        def color(self, color):
            self.color = color
            return self.color

x = Person()
print(x.last_name('Jimmy'))

print(x.Features.color('Brown'))

Instead I get this error:

TypeError: Person.Features.color() missing 1 required positional argument: 'color'

How can I do this correctly?

12
  • 1
    Don't give properties and methods the same name. Use self._color to signify that you're referring to a private member, and not the method again. Commented Jan 9, 2024 at 19:30
  • 2
    The4 code in your question doesn't produce any error. And why do you want to define a class inside of a class? Commented Jan 9, 2024 at 19:30
  • x = Person() print(x.last_name('Jimmy')) print(x.Features.color('Brown')) , This is what produces the error Commented Jan 9, 2024 at 19:32
  • 1
    Don't add code to comments, edit your question. Also, defining an internal class doesn't create the object. You still need to initialise it in init. Commented Jan 9, 2024 at 19:34
  • 3
    Nesting classes like this is of no use. You have oto define a Features class at module level, and add an instance of it to your Person class in its __init__ method. Frameworks do sometimes use nested classes, but that is for the namespace, not for using those as "classes". Commented Jan 9, 2024 at 19:41

2 Answers 2

1

Your inner class is another class definition, just like the outer one.

a_person = Person()
a_feature = Person.Features()

For using it, you need to define it.

x = Person()
print(x.last_name('Jimmy'))
y = x.Features() # Or just Person.Features()
print(y.color('Brown'))

And the reason for the error:

missing 1 required positional argument

It's because you're trying to call the color() function without initializing the Features class. This means that the self argument, which would refer to the initialized class that doesn't exist now, is not passed down to the color function.

So it's giving you the error because it takes your "Brown" as the self parameter and so nothing is given to the color parameter; hence the:

Person.Features.color() missing 1 required positional argument: 'color'
Sign up to request clarification or add additional context in comments.

Comments

1

I would not personally nest classes like this, but if you want to do that for some reason, this is a first step forward. The key here is that as part of the __init__() of Person, we __init__() their Features.

class Person:
    class Features:
        def __init__(self, color=None):
            self.color = color

    def __init__(self, first, middle, last):
        self.first_name = first
        self.middle_name = middle
        self.last_name = last
        self.features = Person.Features()

    def __str__(self):
        return f"{self.last_name}, {self.first_name}\n\tHair Color: {self.features.color}"

person = Person("Jane", "Mary", "Doe")
person.first_name="Sara"
person.features.color = "Red"
print(person)

That should give you:

Doe, Sara
        Hair Color: Red

You also might explore What's the pythonic way to use getters and setters?

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.