__bases__ misleading error message

Chris Angelico rosuav at gmail.com
Sat Jan 24 23:25:51 CET 2015

On Sun, Jan 25, 2015 at 9:09 AM, Mario Figueiredo <marfig at gmail.com> wrote:
> Meaning the interpreter knows a variable's name. Which would allow it to
> produce an error message such as:
>     AttributeError: 'foo' object has no attribute '__bases__'
> For the following code:
>     class Sub:
>         pass
>     foo = Sub()
>     foo.__bases__

Let me explain by way of analogy. You have ten shoeboxes to store your
stuff in. I hand you a thing and say "Here, put this into shoebox #4".
Then someone else comes along and says, "I need the thing from shoebox
#4", so you give him that thing. Now, he hands that thing to someone
else and asks him which shoebox it came out of, just by looking at the
thing itself. How can he say? The thing doesn't have any way of
knowing what shoebox it came out of.

Python names reference objects. But once you get an object, there's no
way of knowing which name was used to get to it. There might be one
such name; there might be more than one; and there might not be any.
You can't identify an object by the name it's bound to, but you can
identify it by something that's always true of the object itself, like
its type.

There are a few cases where names are so useful that they get attached
to the objects themselves. The 'def' and 'class' statements create
objects and also record the names used. But you still can't identify
what name was used to reference something:

>>> def func(x): print("x = %s"%x)
>>> func(123)
x = 123
>>> show = func
>>> show(234)
x = 234
>>> func = "not a function"
>>> func(123)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object is not callable
>>> show(123)
x = 123
>>> show
<function func at 0x7f36744a30d0>

No matter what name I use to reference the function, it's still called
"func". Nobody can ever know that I'm identifying it by the name
'show' now.


More information about the Python-list mailing list