3

I am currently learning OOP and I have created a class that stores a dict as a variable self.foo. I have created a method bar that returns self.foo:

class FooBar:

    def __init__(self):
        self.foo = {}

    def bar(self):
        return self.foo


if __name__ == '__main__':
    FooBar()

My question is this. Calling the class variable directly and using the bar method produce the same results, which is the correct method for accessing self.foo or doesn't it make a difference?

Here are some examples:

>>>test = FooBar()
>>>test.foo['test'] = 'This is a test'
>>>print(test.foo)
'{'test': 'This is a test'}'

>>>test.bar()['test_2'] = 42
>>>print(test.bar())
'{'test': 'This is a test', 'test_2': 42}'
death and gravity
  • 619
  • 1
  • 8
  • 21
  • 1
    "which is the correct method for accessing self.foo" — depends what the class is for and how it is documented. – khelwood May 25 '17 at 13:02
  • 6
    You might want to read about the `@property` decorator: https://stackoverflow.com/a/17330273/295246 – HEADLESS_0NE May 25 '17 at 13:02

2 Answers2

2

Both ways are correct and it doesn't make much difference which one you choose. The approach with the bar(self) method is the classical "getter" approach that is often used in other OO languages to access typically private members but as in python every member is public by default it doesn't make a difference if you use your getter method bar(self) or call the member foo directly.

Alternatively, to the getter method you can also use the @property decorator if you want to access the member foo with a different name. But if you don't need to do anything with the foo member before accessing and returning it by another name you can also simply add a reference to the foo member as self.bar = self.foo in your constructor such that you are able to access the member under a different name. (I think it is overdoing to creating a method or use a property just to access the member under a different name I would use the reference to the member, but that is my personal preference).

However, if you want to mark that the member should be treated as private and should be modified only within the class or with a setter method it is common practice to start the member name with a _ such as in _foo.

2006pmach
  • 361
  • 1
  • 10
  • +1 Great answer. Everything I was going to say. I will add 1 thing. It's not considered pythonic to code getter and setter methods to public members. If you want to access your variables like this, then you should make them private as described in the answer. – SH7890 May 25 '17 at 14:06
0

You should always use property decorator.

If you're directly returning the variable from function then that's wrong, the reader might think that there will be some computation or modification in the called function, but in reality, you're just passing the variable so property decorator will give more clear context to the reader.

class FooBar:

    def __init__(self):
        self.foo = {}
    @property
    def bar(self):
        return self.foo

Then access it like,

>>>test = FooBar()
>>>test.foo['test'] = 'This is a test'
>>>print(test.foo)
'{'test': 'This is a test'}'

>>>test.bar['test_2'] = 42
>>>print(test.bar)
'{'test': 'This is a test', 'test_2': 42}'
harshil9968
  • 3,254
  • 1
  • 16
  • 26