Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #84454 > unrolled thread
| Started by | Mario Figueiredo <marfig@gmail.com> |
|---|---|
| First post | 2015-01-24 10:16 +0000 |
| Last post | 2015-01-24 22:51 +0100 |
| Articles | 8 on this page of 28 — 7 participants |
Back to article view | Back to comp.lang.python
__bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 10:16 +0000
Re: __bases__ misleading error message Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-24 23:43 +1100
Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 22:14 +0100
Re: __bases__ misleading error message Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-24 14:45 -0700
Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 23:09 +0100
Re: __bases__ misleading error message Chris Angelico <rosuav@gmail.com> - 2015-01-25 09:25 +1100
Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 23:33 +0100
Re: __bases__ misleading error message Chris Angelico <rosuav@gmail.com> - 2015-01-25 09:37 +1100
Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 23:59 +0100
Re: __bases__ misleading error message Terry Reedy <tjreedy@udel.edu> - 2015-01-24 16:58 -0500
Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 23:02 +0100
Re: __bases__ misleading error message Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-24 15:16 -0700
Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 23:36 +0100
Re: __bases__ misleading error message Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-25 14:18 +1100
Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-25 12:07 +0100
Re: __bases__ misleading error message Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-01-25 23:00 +1100
Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-25 13:49 +0100
Re: __bases__ misleading error message Marko Rauhamaa <marko@pacujo.net> - 2015-01-25 14:53 +0200
Re: __bases__ misleading error message Terry Reedy <tjreedy@udel.edu> - 2015-01-25 16:35 -0500
Re: __bases__ misleading error message Ian Kelly <ian.g.kelly@gmail.com> - 2015-01-25 19:21 -0700
Re: __bases__ misleading error message Marco Buttu <marco.buttu@gmail.com> - 2015-01-24 23:09 +0100
Re: __bases__ misleading error message Marco Buttu <marco.buttu@gmail.com> - 2015-01-24 15:12 +0100
Re: __bases__ misleading error message Terry Reedy <tjreedy@udel.edu> - 2015-01-24 14:24 -0500
Re: __bases__ misleading error message Mario Figueiredo <marfig@gmail.com> - 2015-01-24 22:03 +0100
Re: __bases__ misleading error message Marco Buttu <marco.buttu@gmail.com> - 2015-01-24 22:51 +0100
Re: __bases__ misleading error message Terry Reedy <tjreedy@udel.edu> - 2015-01-24 19:55 -0500
Re: __bases__ misleading error message Marco Buttu <marco.buttu@gmail.com> - 2015-01-25 11:30 +0100
Re: __bases__ misleading error message Marco Buttu <marco.buttu@gmail.com> - 2015-01-24 22:51 +0100
Page 2 of 2 — ← Prev page 1 [2]
| From | Marco Buttu <marco.buttu@gmail.com> |
|---|---|
| Date | 2015-01-24 23:09 +0100 |
| Message-ID | <ma156n$5qj$1@speranza.aioe.org> |
| In reply to | #84461 |
On 24/01/2015 13:43, Steven D'Aprano wrote: > Mario Figueiredo wrote: > >> > class Sub: >> > pass >> > >> > foo = Sub() >> > >> > Sub.__bases__ >> > foo.__bases__ >> > >> >The last statement originates the following error: >> > >> > AttributeError: 'Sub' object has no attribute '__bases__' > It's a bit ambiguous, but the way to read it is to think of object as a > synonym for instance. ... > >> >Naturally the 'Sub' object has an attribute __bases__. > Correct, in the sense that classes are objects too. But in the sense of > object=instance, no. Isn't ambiguous terminology wonderful? In my opinion it is not ambiguous, because as you say in Python an object is a synonym for instance. We can say in Python an object is an instance of the type object, that's all. And that's why everything is an object in Python: >>> isisntace(foo, object) # For every foo True So a class (a type) is an instance too, an instance of its metaclass. Therefore, the message says that the Sub instance has no attribute '__bases__'. In fact the Sub object (instance) has no attribute '__bases__' because it is not an instance of type, and only types (classes) have this attribute. So if we want to find some differences between objects, we have to distinguish between types (classes) and non-types (non-classes) objects, and not between objects and classes. In the Python documentation there is also a bit of confusion about this... In the descriptor howto: "The details of invocation depend on whether obj is an object or a class" :/ -- Marco Buttu
[toc] | [prev] | [next] | [standalone]
| From | Marco Buttu <marco.buttu@gmail.com> |
|---|---|
| Date | 2015-01-24 15:12 +0100 |
| Message-ID | <mailman.18142.1422260120.18130.python-list@python.org> |
| In reply to | #84461 |
On 24/01/2015 13:43, Steven D'Aprano wrote: > Mario Figueiredo wrote: >> > class Sub: >> > pass >> > >> > foo = Sub() >> > >> > Sub.__bases__ >> > foo.__bases__ >> > >> >The last statement originates the following error: >> > >> > AttributeError: 'Sub' object has no attribute '__bases__' > It's a bit ambiguous, but the way to read it is to think of object as a > synonym for instance. In my opinion it is not ambiguous, because as you say in Python an object is a synonym for instance. We can say in Python an object is an instance of the type object, that's all. And that's why everything is an object in Python: >>> isisntace(foo, object) # For every foo True So a class (a type) is an instance too (of its metaclass). Therefore, the message says that the Sub instance has no attribute '__bases__'. In fact the Sub object (instance) has no attribute '__bases__' because it is not an instance of type, and only types (classes) have this attribute. That means in Python sometimes, like the OP one, we have to underline the difference between types (classes) and non-types (non-classes) objects, instead of between objects and classes. The problem is in the Python documentation there is also a bit of confusion about this... In the descriptor howto: "The details of invocation depend on whether obj is an object or a class" :/ -- Marco Buttu INAF-Osservatorio Astronomico di Cagliari Via della Scienza n. 5, 09047 Selargius (CA) Phone: 070 711 80 217 Email: mbuttu@oa-cagliari.inaf.it
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2015-01-24 14:24 -0500 |
| Message-ID | <mailman.18093.1422127493.18130.python-list@python.org> |
| In reply to | #84454 |
On 1/24/2015 5:16 AM, Mario Figueiredo wrote:
>
> Consider the following code at your REPL of choice
> class Sub:
> pass
>
> foo = Sub()
>
> Sub.__bases__
> foo.__bases__
>
> The last statement originates the following error:
This is an anomalous situation. Normally, if a class has an attribute,
instances have the same attribute (unless overriden). But this does not
matter.
> AttributeError: 'Sub' object has no attribute '__bases__'
In this message, 'Sub' is an adjective, modifying 'object, not naming
it. If you attend to the last line of the traceback
foo.__bases__
which is an integral part of the total error message, the interpretation
of this exception message should be clear.
> AttributeError: 'Sub' instance has no attribute '__bases__',
'Sub' is an instance of 'type', so "'Sub' instance" could also be taken
to mean the class if the traceback were ignored. But that would also be
wrong. An attribute error for the class, such as "Sub.xyz" give a
message ending with
...
Sub.xyz
AttributeError: type object 'Sub' has no attribute 'xyz'
--
Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Mario Figueiredo <marfig@gmail.com> |
|---|---|
| Date | 2015-01-24 22:03 +0100 |
| Message-ID | <MPG.2f2e26f46dbc1475989691@nntp.aioe.org> |
| In reply to | #84486 |
In article <mailman.18093.1422127493.18130.python-list@python.org>,
tjreedy@udel.edu says...
> > AttributeError: 'Sub' object has no attribute '__bases__'
>
> In this message, 'Sub' is an adjective, modifying 'object, not naming
> it. If you attend to the last line of the traceback
>
My first reaction is to look at 'Sub' as a noun, not an adjective, since
I know that NAME well on my code as being a noun. Meanwhile I know that
objects may be qualified (adjectivized) as class objects or instance
objects. So, I also happen to look at the word "object" as an adjective,
as Python object semantics would me do.
What you propose is that I look at that phrase the other way around,
which is kind of contrarian to how you actually use them in your code.
> > AttributeError: 'Sub' instance has no attribute '__bases__',
>
> 'Sub' is an instance of 'type', so "'Sub' instance" could also be taken
> to mean the class if the traceback were ignored.
I agree. Sub instance is still somewhat ambiguous. So, maybe:
AttributeError: Instance of object 'Sub' has no attribute
'__bases__'
[toc] | [prev] | [next] | [standalone]
| From | Marco Buttu <marco.buttu@gmail.com> |
|---|---|
| Date | 2015-01-24 22:51 +0100 |
| Message-ID | <54C413E4.5060208@gmail.com> |
| In reply to | #84486 |
On 24/01/2015 20:24, Terry Reedy wrote:
> On 1/24/2015 5:16 AM, Mario Figueiredo wrote:
>>
>> Consider the following code at your REPL of choice
>
>> class Sub:
>> pass
>>
>> foo = Sub()
>>
>> Sub.__bases__
>> foo.__bases__
>>
>> The last statement originates the following error:
>
> This is an anomalous situation. Normally, if a class has an attribute,
> instances have the same attribute (unless overriden). But this does not
> matter.
That is not true: if a class has an attribute, you can not say its
instances have the same attribute. You can just say if a type defines an
attribute, all its instances have that attribute. Look at this example:
>>> class Foo(type):
... foo = 33
...
>>> Foo.foo
33
>>> MyClass = Foo('MyClass', (), {})
MyClass is an instance of Foo, so it must have the attribute foo:
>>> isinstance(MyClass, Foo)
True
>>> MyClass.foo
33
But an instance of MyClass is not an instance of Foo, and so MyClass()
must not have the attribute foo. In fact:
>>> m = MyClass()
>>> isinstance(m, Foo)
False
>>> m.foo
Traceback (most recent call last):
...
AttributeError: 'MyClass' object has no attribute 'foo'
--
Marco Buttu
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2015-01-24 19:55 -0500 |
| Message-ID | <mailman.18117.1422147330.18130.python-list@python.org> |
| In reply to | #84497 |
On 1/24/2015 4:51 PM, Marco Buttu wrote: > On 24/01/2015 20:24, Terry Reedy wrote: > >> On 1/24/2015 5:16 AM, Mario Figueiredo wrote: >>> >>> Consider the following code at your REPL of choice >> >>> class Sub: >>> pass >>> >>> foo = Sub() >>> >>> Sub.__bases__ >>> foo.__bases__ >>> >>> The last statement originates the following error: >> >> This is an anomalous situation. 'This situation' being that Someclass.attro works but Someclass().attro raises. Normally, if a class has an attribute, In other words, if 'Someclass.attro' evaluates to an object >> instances have the same attribute then 'Someclass().attro' *normally* evaluates to the same object >> (unless overriden). (unless 'Someclass().attro' has been bound to a different object) because attribute lookup on an instance reverts to attribute lookup on the class and even its super classes (__bases__). Someclass.__bases__ is special; it is not listed by dir(Someclass), and it is not accessible via an instance. > That is not true: What I said, as I meant it to be understood, is true. -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Marco Buttu <marco.buttu@gmail.com> |
|---|---|
| Date | 2015-01-25 11:30 +0100 |
| Message-ID | <ma2gjf$3na$1@speranza.aioe.org> |
| In reply to | #84533 |
On 25/01/2015 01:55, Terry Reedy wrote:
> 'This situation' being that Someclass.attro works but Someclass().attro
> raises...
>
> In other words, if 'Someclass.attro' evaluates to an object ...
> then 'Someclass().attro' *normally* evaluates to the same object
I am sorry Terry, but I do not agree, because the word "normally" in
this context does not have any meaning, and instroduces just confusion.
In facts this is exactly the case where "Someclass.attro' evaluates to
an object" *but* hasattr(Someclass(), 'attro'), as expected, is False.
What do you mean with "normally"?
> because attribute lookup on an instance reverts to attribute lookup on
> the class and even its super classes
Here's the point. The __bases__ attribute is defined by the class type.
So if isinstance(obj, type) is true, then hasattr(obj, '__bases__') is
true. In the OP case:
>>> class Sub: # Python 3
... pass
...
>>> isinstance(Sub, type)
True
>>> hasattr(Sub, '__bases__')
True
But Sub() is not an instance of type (because Sub is not a subclass of
type), and so Sub() does not have to get the attributes, like __bases__,
from type, and here's we are:
>>> foo = Sub()
>>> isinstance(foo, type)
False
>>> foo.__bases__
Traceback (most recent call last):
...
AttributeError: 'Sub' object has no attribute '__bases__'
In other words, speaking about the lookup machinery, because '__bases__'
is not in foo.__dict__ Python looks for __bases__ in Sub.__dict__, but
it does not found it. So it looks in the Sub bases, and we went back to
the point: Sub is an instance of type, not a subclass of type.
> Someclass.__bases__
> is special; it is not listed by dir(Someclass), and it is not accessible
> via an instance.
In my point of view no attribute is special (maybe just a descriptor is
a bit special, in some ways). To undestand what happens in these
situations, we do not have to give a special meaning to the attribute.
Given `obj.attr`, we just have to know what kind of object is `obj`:
usually, like in this case, we have to differentiate between classes and
non-classes objects. In fact __bases__ is not listed by dir(Sub) because
Sub is a class, and the distinction between classes and non-classes
objects matters, especially for dir()
--
Marco Buttu
[toc] | [prev] | [next] | [standalone]
| From | Marco Buttu <marco.buttu@gmail.com> |
|---|---|
| Date | 2015-01-24 22:51 +0100 |
| Message-ID | <mailman.18100.1422136299.18130.python-list@python.org> |
| In reply to | #84486 |
On 24/01/2015 20:24, Terry Reedy wrote:
> On 1/24/2015 5:16 AM, Mario Figueiredo wrote:
>>
>> Consider the following code at your REPL of choice
>
>> class Sub:
>> pass
>>
>> foo = Sub()
>>
>> Sub.__bases__
>> foo.__bases__
>>
>> The last statement originates the following error:
>
> This is an anomalous situation. Normally, if a class has an attribute,
> instances have the same attribute (unless overriden). But this does not
> matter.
That is not true: if a class has an attribute, you can not say its
instances have the same attribute. You can just say if a type defines an
attribute, all its instances have that attribute. Look at this example:
>>> class Foo(type):
... foo = 33
...
>>> Foo.foo
33
>>> MyClass = Foo('MyClass', (), {})
MyClass is an instance of Foo, so it must have the attribute foo:
>>> isinstance(MyClass, Foo)
True
>>> MyClass.foo
33
But an instance of MyClass is not an instance of Foo, and so MyClass()
must not have the attribute foo. In fact:
>>> m = MyClass()
>>> isinstance(m, Foo)
False
>>> m.foo
Traceback (most recent call last):
...
AttributeError: 'MyClass' object has no attribute 'foo'
--
Marco Buttu
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.python
csiph-web