0

I am new to python and to object-oriented programming. I have a basic question on OOP using python. Suppose there is a class with some instance variables initialized. Later on, I need to add many more instance variables. I can do that with object.attribute = value outside the class. The code in the class does not set the attributes/variables.

Will the program not become difficult to maintain when it grows large? There would be instance variable assignments strewn everywhere in the code except inside the class. Isn't it a better idea to have those assignments in the class with self.attribute = value, where they can be tracked easily? What is the right approach?

3
  • 1
    Yeeees…!? I'd start with: why exactly are you assigning all those properties to your object? Commented May 11, 2017 at 3:07
  • 1
    If you have dynamic data to store you should consider using a dictionary. Commented May 11, 2017 at 3:08
  • I am creating a Person object, initialized with name and age. Then I want to add to this object attributes like postal address, email and many others, obtained as user input. Commented May 11, 2017 at 3:14

1 Answer 1

3

You've reached a fork: on the left lies "in general," while on the right you can see "in specific."

In general, yes, you want your object's members to be determined by the class that defines the object. That's the whole point of having a class - to contain and specify similar behavior by grouping together some code (methods) and some data (instance and class variables).

In specific, however, sometimes you have a function that just needs to hang some data someplace. It may have nothing to do with the class at all - just "have I seen you before" or "here is the memoized result of a computation."

So in general, yes, you should be striving to put all your class-related data into your class. But don't get too bent out of shape if there happens to be some specific case where that doesn't happen.

Update:

After some comments, let's consider examples of use:

  1. Use of attributes by methods:

    If you have one or more methods that use an attribute, but it's not generally available to the public, then you can delay setting the attribute until you use it:

    class Window:
        def print_text(self, text):
            if self._bg_color is None:
                self._bg_color = WHITE
    
            # continue...
    

    This attribute won't have to be in your __init__ method, since you are taking responsibility for making sure it is set before use in your own methods.

  2. Use of attributes as part of the API of the class.

    In the case where your attribute is part of the API of the class, you cannot control how the attribute will be used. Some dumb user is going to do whatever thing they want, and when it doesn't work, they'll be complaining about your code on Stack Overflow. ;-)

    In this case, you have two choices: (a) you can ensure that it is always set, or (b) you can intercept accesses to the member (with an @property method) and set it on demand.

    class Color:
        def __init__(self, r, g, b):
            self.r = r
            self.g = g
            self.b = b
            # Option (a): Ensure properties are always set:
            self.h, self.s, self.v = _compute_hsv(r, g, b)
    
        # Option (b): Intercept property access and compute on demand
        @property
        def h(self):
            if self._h is None:
                self._h, self._s, self._v = _compute_hsv(self.r, self.g, self.b)
            return self._h
    
        # likewise for s, v
    
Sign up to request clarification or add additional context in comments.

10 Comments

But if I put all the class-related data into the class, I need to use setters and that's not recommended in python.
You can use a property decorator instead of Java-style getters and setters - programiz.com/python-programming/property
You don't need to use setters: there's a difference between directly setting a known attribute, and just randomly hanging a new attribute on an object. When you set object.attribute = value outside the class, then nobody knows about the attribute. If you set object.attribute = None in your __init__() constructor, and then set object.attribute = 1 somewhere else, that's okay.
@Pramod A property would be appropriate if I am doing something with the data. But for simple assignments, a property decorator for each of the many instance variables would make the class bulky.
Thanks a lot Austin for all the comments and the post. I guess I cannot continue to comment...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.