8

I understand that in python, whenever you access a class/instance variable, it will call __getattribute__ method to get the result. However I can also use obj.__dict__['x'] directly, and get what I want.

I am a little confused about what is the difference? Also when I use getattr(obj, name), is it calling __getattribute__ or obj.__dict__[name] internally?

Thanks in advance.

cizixs
  • 12,931
  • 6
  • 48
  • 60
  • http://stackoverflow.com/questions/3278077/difference-between-getattr-vs-getattribute should clear your doubt. – Aashish P Dec 31 '15 at 08:51
  • @AashishP thanks for commenting. But that post explains difference between `__getattr__` and `__getattribute__`. It seems that `getattr` has little to do with `__getattr__`, so are you implying that `getattr` actually equals to `obj.__dict__[name]`? – cizixs Dec 31 '15 at 08:55
  • Yeah, right. I tried to dig CPython source code and here is what I found, in plain language, http://stackoverflow.com/questions/24863787/python-the-getattribute-method-and-descriptors – Aashish P Dec 31 '15 at 09:19
  • 1
    Also, you can check C implementation of `getattr` [here](https://github.com/python/cpython/blob/1364858e6ec7abfe04d92b7796ae8431eda87a7a/Python/bltinmodule.c#L985) – Aashish P Dec 31 '15 at 09:21
  • @AashishP thanks, I will read the source code. – cizixs Dec 31 '15 at 09:57

3 Answers3

2

Attributes in __dict__ are only a subset of all attributes that an object has.

Consider this class:

class C:
    ac = "+AC+" 
    def __init__(self):
        self.ab = "+AB+" 

    def show(self):
        pass

An instance ic = C() of this class will have attributes 'ab', 'ac' and 'show' (and few others). The __gettattribute__ will find them all, but only the 'ab' is stored in the ic.__dict__. The other two can be found in C.__dict__.

VPfB
  • 14,927
  • 6
  • 41
  • 75
2

__getattribute__() method is for lower level attribute processing.

Default implementation tries to find the name in the internal __dict__ (or __slots__). If the attribute is not found, it calls __getattr__().

UPDATE (as in the comment):

They are different ways for finding attributes in the Python data model. They are internal methods designed to fallback properly in any possible situation. A clue: "The machinery is in object.__getattribute__() which transforms b.x into type(b).__dict__['x'].__get__(b, type(b))." from docs.python.org/3/howto/descriptor.html

tuned
  • 1,085
  • 10
  • 14
  • Does that mean `__getattribute__` will call try find attribute in `__dict__`, and do more things? In other word: `__getattribute__` is a superset of `__dict__` method. – cizixs Dec 31 '15 at 10:00
  • They are different ways for finding attributes in the Python data model. They are internal methods designed to fallback properly in any possible situation. A clue: "The machinery is in `object.__getattribute__()` which transforms `b.x` into `type(b).__dict__['x'].__get__(b, type(b))`." from https://docs.python.org/3/howto/descriptor.html – tuned Dec 31 '15 at 10:49
0

Not every python object has a dictionary where it's attributes are stored, there are slots, properties and attributes, that are calculated, wenn needed. You can also overwrite __getattribute__ and __getattr__. Attribute access is more complicated, than a simple dictionary lookup. So the normal way to access attribute is by

obj.x

wenn you have a variable with attribute name:

getattr(obj, name)

Normally you shouldn't use the internal attributes __xxx__.

Daniel
  • 42,087
  • 4
  • 55
  • 81
  • Thanks for the clarification. I read somewhere that when I use `obj.x`, it will can `__getattribute__`, if not found, `__getattr__` will be called. Where is the internal `__dict__` variable? If it is used when I access an instance attribute, and not recommended to use it directly, what is the point of it? – cizixs Dec 31 '15 at 09:00