0

How frequently should you use __getattr__ in Python, rather than normal methods?

Which of these would be considered better?

class A:
    def __getattr__(self, attribute):
        if attribute == "spam":
            return self._spam * 100
        elif attribute == "eggs":
            return "fried" + self._eggs
        raise AttributeError

or

class B:
    def get_spam(self):
        return self._spam * 100

    def get_eggs(self):
        return "fried" + self._eggs
rlms
  • 10,650
  • 8
  • 44
  • 61

1 Answers1

3

Instead of __getattr__ or accessor methods, use the @property decorator:

class B(object):
    @property
    def spam(self):
        return self._spam * 100

    @property
    def eggs(self):
        return "fried" + self._eggs

Use __getattr__ only to support dynamic attributes, where the number and names of the attributes are not known at class definition time.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Why `@property` and not accessor methods? – Reloader Jun 14 '14 at 14:14
  • 2
    @Reloader: why use an accessor method when attribute access is cleaner? If an attribute makes sense from an API perspective (it naturally behaves like an attribute, doesn't take arguments and has a dynamic nature), why have the end user of your object explicitly call to get the value? – Martijn Pieters Jun 14 '14 at 15:12
  • I don't know :) I'm trying to learn programming and Python, and that's why I'm asking. Just seeing that yours and OP's `classB` is nearly the same, except you have decorator implemented, but functionality is the same. – Reloader Jun 14 '14 at 15:34
  • 1
    @Reloader The functionality isn't the same. I would do `a_B.get_spam()`, this would do `a_B.spam` (no function call). – rlms Jun 14 '14 at 16:53
  • Do all getter and setter methods should be decorated? – Reloader Jun 14 '14 at 22:58
  • 1
    @Reloader: it is more Pythonic to use attributes. If you need a dynamic attribute, provide one by using `property`. The easiest way to use `property` is as a decorator. – Martijn Pieters Jun 14 '14 at 23:33
  • Thank you for the clarification! If I understand clearly, `property`'s only usage is to make accessor methods _callable_? What you mean by 'dynamic attribute'? – Reloader Jun 15 '14 at 00:26
  • 1
    @Reloader: An attribute whose value depends on other factors or state; something that requires calculation, usually. – Martijn Pieters Jun 15 '14 at 00:33
  • Do accessor methods and/or `property` should be used only with protected or private attributes? Is there advantage of using this methods in comparation to direct access to attributes (instance.attribute), if they are public? I've seen the code where getter and setter methods are defined although attributes are public, and that's confusing me. Thanks. – Reloader Jun 15 '14 at 02:01
  • 1
    @Reloader: There are no private or protected attributes in Python. *All* attributes are public. Underscores are only a naming convention. – Martijn Pieters Jun 15 '14 at 02:01
  • 1
    @Reloader: last comment here, this is not a chat room after all: [Python name mangling: When in doubt, do what?](http://stackoverflow.com/q/7456807) – Martijn Pieters Jun 15 '14 at 02:04