1

I've got the following code under python command line. I expect that when I visit an attribute, getattribute is automatically called. But I don't see the result

class D:
  def __getattribute__(s,*a,**ka):
    print "__getattribute__"
    return object.__getattribute__(s,*a,**ka)

  def __getattr__(s,name):
    print "__getattr__"
    return name

  def __get__(s,instance,owner):
    print "__get__"
    return s
  a='abc'

class C2(object):
    d=D()

>>> d=D()
>>> c2=C2()
>>> print d.a
abc
>>> print d.zzz
__getattr__

No "getattribute" printed. Why?

Troskyvs
  • 7,537
  • 7
  • 47
  • 115
  • Possible duplicate of [Difference between \_\_getattr\_\_ vs \_\_getattribute\_\_](http://stackoverflow.com/questions/3278077/difference-between-getattr-vs-getattribute) – anthony sottile Nov 29 '16 at 02:07

2 Answers2

2

You're running Python 2, and your D class is old-style, not new-style. __getattribute__ is used for new-style classes only.

As a rule, I put the following at the top of all modules that might be run under Python 2, to ensure all classes defined are implicitly new-style (and cause no harm on Py3, where it's ignored):

__metaclass__ = type

Alternatively, you can explicitly inherit from object (or any other new-style class that fits your needs) to get new-style classes.

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
1

Change class D to new style class D(object):

class D(object):
  def __getattribute__(s,*a,**ka):
    print "__getattribute__"
    return object.__getattribute__(s,*a,**ka)

  def __getattr__(s,name):
    print "__getattr__"
    return name

  def __get__(s,instance,owner):
    print "__get__"
    return s
linpingta
  • 2,324
  • 2
  • 18
  • 36