9

I have a question that is puzzling me recently about which is the best way to retrieve attributes from outside.

Let say I have a class:

class Thing:
    def __init__(self, whatever):
        self.whatever = whatever

x = Thing('foo')

Now I know that if I want to retrieve whatever attribute I can do this:

x.whatever

I have the habit (probably because I come from other oo languages) to define methods to retrieve class attributes as needed and use them insted of retrieve them directly, like:

class Thing:
    def __init__(self, whatever):
        self.whatever = whatever

    def getWhatever(self):
        return self.whatever

In my little experience I've found that using this approach make things easier to mantain in the long term because if I edit the structure of data attributes I have to edit only the specific method.

But since I am not really a python veteran I'd love to know if I am doin' it right or if some other approaches are better and more pythonic. Thoughts?

Yannick Loiseau
  • 1,394
  • 8
  • 8
gbr
  • 1,061
  • 2
  • 9
  • 16
  • 1
    Here, `whatever` is not a *class* attribute, but an instance one. Class attributes pertains to the class, and have the same value for every instances. – Yannick Loiseau Sep 17 '11 at 15:15

3 Answers3

14

Defining explicit getters and setters is a bad practice in Python. Instead, use properties:

class Thing(object): # New-style class
    def __init__(self, whatever):
        self._whatever = whatever

    @property
    def whatever(self):
        return self._whatever # Insert complicated calculation here

So instead of pre-planning by using get methods, just introduce a property when you actually need advanced behavior, and not any earlier.

Community
  • 1
  • 1
phihag
  • 278,196
  • 72
  • 453
  • 469
8

@phihag has the right idea, and mentions in their answer, but to be more explicit about it: The first step is simply to use the attribute directly:

class Thing(object):
    def __init__(self, whatever):
        self.whatever = whatever


t = Thing(12)
assert t.whatever == 12

Later, if you find you need to make the whatever attribute more sophisticated, you can turn it into a property:

class Thing(object):
    def __init__(self, whatever):
        self._whatever = whatever

    @property
    def whatever(self):
        return something_complicated(self._whatever)


t = Thing(12)
assert t.whatever == 12

This way, the calling code doesn't change, and you have a nice clean API to your object.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
0

check python property() http://docs.python.org/library/functions.html#property

Dyno Fu
  • 8,753
  • 4
  • 39
  • 64