ffConundrums
ffConundrums

Reputation: 865

Why is the argument passed to __getattribute__ not recognized?

A very basic question.

I have some dummy class:

class SomeClass:
    """ just a docstring"""

    a = 5

dir(SomeClass), returns the following attributes associated with this class:

>>> dir(SomeClass)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__form
at__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_s
ubclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
 '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclas
shook__', '__weakref__', 'a']
>>>

I noticed that if I make a call to SomeClass.__getattribute__, even if I pass an argument to it (which it says it requires), the error message says I am not passing any argument.

>>> SomeClass.__getattribute__('a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: expected 1 arguments, got 0
>>>

Note - it's not that I have a use-case for wanting to call __getattribute__ in this way. (In fact seems incorrect to do so, that I'd want to call it on an instance of SomeClass instead, which DOES work). I'm just curious about the behavior of __getattribute__: why does the error message say it got 0 arguments, when I am actually passing an argument to it? I'm not disputing that my usage is incorrect - just, why doesn't __getattribute__ recognize that it was passed an argument?

I did notice that __getattribute__ is listed as a 'slotwrapper'. Does this have to do with it? I'm having a hard time figuring out what is the real difference between calling a slotwrapper and calling a function. Does this slotwrapper toss out the argument I have passed it, because of the way I've called it?

>>> SomeClass.__getattribute__
<slot wrapper '__getattribute__' of 'object' objects>
>>>

Upvotes: 3

Views: 1859

Answers (2)

isthisthat
isthisthat

Reputation: 165

You can also try getattr(SomeClass, "a"). This worked for me in a similar case.

Upvotes: 2

Blckknght
Blckknght

Reputation: 104712

The function __getattribute__ that you're calling is a method. It expects two arguments. The first argument is self, which will usually be an instance of SomeClass (and usually gets provided automatically when you call via an instance: instance.__getattribute__). The second argument is the name of an attribute to look up.

When you call SomeClass.__getattribute__("a"), you're passing "a" as self. That's not a very useful thing to do. If you provided a second argument too, it might even work (since SomeClass.__getattribute__ is inherited from object, as is str.__getattribute__). It will be looking up attributes on the string you pass in though, not on anything related to SomeClass.

The only odd behavior is that it says got zero arguments (and expected one), rather than the saying that it got one argument and expected two. That part of the issue might be a (minor) bug.

Upvotes: 3

Related Questions