Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: About __class__ of an int literal

Reply
Thread Tools

Re: About __class__ of an int literal

 
 
MRAB
Guest
Posts: n/a
 
      09-29-2010
On 29/09/2010 01:19, Terry Reedy wrote:
> On 9/28/2010 5:27 AM, AlexWalk wrote:
>> In python 3.1.2(I'm using windows edition, 32bit), accessing __class__
>> of an int literal will raise a SyntaxException, while other literals
>> will not. For example. 1.__class__ is an error, while 1.1.__class__ runs
>> ok.

>
> Third solution:
> >>> type(0) is 0 .__class__

> True
>
> A person using instances of a class should seldom use special names
> directly. They are, in a sense, implementation details, even if documented.
> The idiom "if __name__ == '__main__':" is an exception.
>

__file__ is another exception.
 
Reply With Quote
 
 
 
 
Steven D'Aprano
Guest
Posts: n/a
 
      09-29-2010
On Wed, 29 Sep 2010 02:20:55 +0100, MRAB wrote:

> On 29/09/2010 01:19, Terry Reedy wrote:


>> A person using instances of a class should seldom use special names
>> directly. They are, in a sense, implementation details, even if
>> documented. The idiom "if __name__ == '__main__':" is an exception.
>>

> __file__ is another exception.



As are __iter__, __next__, __add__, __dict__, and, yes, __class__, to say
nothing of all the other special methods.

I'm afraid that I have to disagree with Terry here. Double-underscore
special variables don't start with double underscores because they're
implementation details, or to indicate that they're private. They are
reserved names for attributes or methods that have special meaning to
Python.

An implementation that didn't use __dict__ for the namespace of an
ordinary class, or didn't call __add__ for the + operator, would be
considered to be buggy.

Naturally one has to be careful about the assumptions you make with such
special methods. You shouldn't assume, for example, that all classes will
have a __dict__ attribute. If the class has __slots__ defined, it may
not. But I think that it is safe to assume any object will have a
__class__ attribute. At least, I'd report it as a bug if I found one that
didn't.

(This may change in the future. Given type(), and isinstance(), I'm not
sure what value __class__ adds.)




--
Steven
 
Reply With Quote
 
 
 
 
Hrvoje Niksic
Guest
Posts: n/a
 
      09-29-2010
Steven D'Aprano <(E-Mail Removed)> writes:

> On Wed, 29 Sep 2010 02:20:55 +0100, MRAB wrote:
>
>> On 29/09/2010 01:19, Terry Reedy wrote:

>
>>> A person using instances of a class should seldom use special names
>>> directly. They are, in a sense, implementation details, even if
>>> documented. The idiom "if __name__ == '__main__':" is an exception.
>>>

>> __file__ is another exception.

>
>
> As are __iter__, __next__, __add__, __dict__, and, yes, __class__, to
> say nothing of all the other special methods.


I think by "person using instances of a class" Terry referred to the
user of a class as opposed to the implementor. In that sense the user
should be calling iter(foo) instead of foo.__iter__(), next(foo) instead
of foo.__next__(), and foo+bar instead of foo.__add__(bar). Direct
calls to special-name methods, such as __len__, often indicate that the
programmer hasn't grasped how those methods are intended to be used in
Python.

Obviously, none of this applies to __dict__, __class__, and friends, nor
does it apply to cases where you know what you're doing, such as
invoking __<method>__ of a superclass.

> (This may change in the future. Given type(), and isinstance(), I'm not
> sure what value __class__ adds.)


None whatsoever. __class__ used to be necessary to tell the appart
instances of different old-style classes:

>>> class X: pass # old-style

....
>>> X().__class__

<class __main__.X at 0xb772f2fc>
>>> type(X())

<type 'instance'>

Now that classes produce real types, they are equivalent.
 
Reply With Quote
 
Terry Reedy
Guest
Posts: n/a
 
      09-29-2010
On 9/29/2010 8:34 AM, Hrvoje Niksic wrote:
> Steven D'Aprano<(E-Mail Removed)> writes:
>
>> On Wed, 29 Sep 2010 02:20:55 +0100, MRAB wrote:
>>
>>> On 29/09/2010 01:19, Terry Reedy wrote:

>>
>>>> A person using instances of a class should seldom use special names
>>>> directly. They are, in a sense, implementation details, even if
>>>> documented. The idiom "if __name__ == '__main__':" is an exception.
>>>>
>>> __file__ is another exception.


>> As are __iter__, __next__, __add__, __dict__, and, yes, __class__, to
>> say nothing of all the other special methods.


I strongly disagree.

> I think by "person using instances of a class" Terry referred to the
> user of a class as opposed to the implementor.


Yes.

> In that sense the user
> should be calling iter(foo) instead of foo.__iter__(), next(foo) instead
> of foo.__next__(), and foo+bar instead of foo.__add__(bar).


Yes. Guido added iter() and next() to the list of built-in functions,
even though they seem reduncant.. I believe it is his intention that the
use of special names outside of class statements should be fairly rare.

If I remember right, in the old, pre-2.2 system that separated built-in
types and user-written classes, the builtins did not have accessible
special method attributes. They are only for customizing user classes.
So one could not have generically written foo.__add__(bar).
Special-method attribute were added to builtins so that they could be
inherited (or replaced) by user-written subclasses, not so that one
could replace normal syntax.

> Direct
> calls to special-name methods, such as __len__, often indicate that the
> programmer hasn't grasped how those methods are intended to be used in
> Python.


Right. That fact that *Python* interpreters implement syntax with
special methods is an implementation detail of the *language*. The
importance is that it allow *writers* of new classes to rather easily
imitate built-in classes so that their classes seamlessly plug into the
syntax.

--
Terry Jan Reedy

 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      09-30-2010
On Wed, 29 Sep 2010 14:46:18 -0400, Terry Reedy wrote:

>> In that sense the user
>> should be calling iter(foo) instead of foo.__iter__(), next(foo)
>> instead of foo.__next__(), and foo+bar instead of foo.__add__(bar).

>
> Yes. Guido added iter() and next() to the list of built-in functions,
> even though they seem reduncant.. I believe it is his intention that the
> use of special names outside of class statements should be fairly rare.


Fairly rare but not non-existent.

For example, there's nothing wrong with using a callback function of
(say) instance.__sub__ instead of lambda b, a=instance: a - b. Not only
is the direct call to the method slightly faster, but more importantly
it's easier to read and more clear to intent.

Admittedly beginners may find instance.__sub__ to be a tad mysterious,
but then beginners are likely to find the lambda form with its two
arguments and default value mysterious too.



> If I remember right, in the old, pre-2.2 system that separated built-in
> types and user-written classes, the builtins did not have accessible
> special method attributes.


Yes, that's correct. But we're talking about Python *now*, not back in
the mists of time before new-style classes. Would you argue that users
shouldn't use decorators, iterators or closures because Python 2.1 didn't
have them? I don't think so.


> They are only for customizing user classes.


Say "were" rather than "are" and I will agree with you.

Say "primarily for" rather than "only" and I will also agree with you.


> So one could not have generically written foo.__add__(bar).
> Special-method attribute were added to builtins so that they could be
> inherited (or replaced) by user-written subclasses, not so that one
> could replace normal syntax.


Of course one shouldn't prefer seq.__len__() over len(seq). But that's a
readability issue, and not because Python implementations are free to
change __len__ to something else.

If I gave the opposite impression, that was not my intention and I'm
sorry for the failure to be more clear.



>> Direct
>> calls to special-name methods, such as __len__, often indicate that the
>> programmer hasn't grasped how those methods are intended to be used in
>> Python.

>
> Right. That fact that *Python* interpreters implement syntax with
> special methods is an implementation detail of the *language*. The
> importance is that it allow *writers* of new classes to rather easily
> imitate built-in classes so that their classes seamlessly plug into the
> syntax.


If I've understood this paragraph correctly, you're trying to say that
since *other languages* that aren't Python are free to implement syntax
features using some other mechanism, *Python* developers shouldn't use
special methods because they are implementation details.

If we're prohibited from using anything which is an implementation detail
of "the *language*" (your emphasis), then we can't use *anything*. Yes,
special methods are an implementation detail of Python, but only in the
same sense that it is an implementation detail of Python that we write
this:

def f(a, b):
x = a + b
return math.sqrt(x)


rather than this:

function f(a, b: integer):float:
var
x: integer;
begin
x := a + b;
f := sqrt(x)
end;



--
Steven
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      09-30-2010
On Wed, 29 Sep 2010 14:34:33 +0200, Hrvoje Niksic wrote:

> Steven D'Aprano <(E-Mail Removed)> writes:
>> (This may change in the future. Given type(), and isinstance(), I'm not
>> sure what value __class__ adds.)

>
> None whatsoever. __class__ used to be necessary to tell the appart
> instances of different old-style classes:
>
>>>> class X: pass # old-style

> ...
>>>> X().__class__

> <class __main__.X at 0xb772f2fc>
>>>> type(X())

> <type 'instance'>
>
> Now that classes produce real types, they are equivalent.



I've been thinking about this, and I think that there may be a use-case
for changing __class__ manually. I'm not entirely sure if this is a good
idea or not, I'd need to spend some time experimenting, but imagine a
class that wraps another object and uses delegation instead of
inheritance.

If you also set __class__ (on the class itself, naturally, not the
instance) appropriately, then type(instance) and instance.__class__ will
be different. type() will return the "real" type of the delegation class,
while instance.__class__ returns the class that it is trying to be.

And of course, presumably metaclasses can do anything they like with
__class__, for good or ill.

I'm not sure if and when this would be useful, but it's a hint that
perhaps the distinction is not entirely meaningless.



--
Steven
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Difference between int i, j; and int i; int j; arun C Programming 8 07-31-2006 05:11 AM
int a[10]; int* p=(int*)((&a)+1); But why p isn't equal to ((&a)+1)? aling C++ 8 10-20-2005 02:42 PM
What's wrong with rpc-literal? Why use doc-literal? Anonieko Ramos ASP .Net Web Services 0 09-27-2004 09:06 AM
int main(int argc, char *argv[] ) vs int main(int argc, char **argv ) Hal Styli C Programming 14 01-20-2004 10:00 PM
dirty stuff: f(int,int) cast to f(struct{int,int}) Schnoffos C Programming 2 06-27-2003 03:13 AM



Advertisments