From: Steven D'Aprano on
On Wed, 28 Jul 2010 08:47:52 -0700, Carl Banks wrote:

> On Jul 28, 7:32 am, Steven D'Aprano <st...(a)REMOVE-THIS-
> cybersource.com.au> wrote:
>> On Wed, 28 Jul 2010 09:35:52 -0400, wheres pythonmonks wrote:
>> > Thanks ... I thought int was a type-cast (like in C++) so I assumed I
>> > couldn't reference it.
>>
>> Python doesn't have type-casts in the sense of "tell the compiler to
>> treat object of type A as type B instead". The closest Python has to
>> that is that if you have an instance of class A, you can do this:
>>
>> a = A()  # make an instance of class A a.__class__ = B  # tell it that
>> it's now class B
>>
>> and hope that it won't explode when you try to use it :/
>
> Type casts in C and non-pathlogical C++ don't modify the object they are
> casting.
>
> int (and str, float, etc.) is the closest thing to a type cast in
> Python.


Perhaps I have been misinformed, but my understanding of C type-casts is
that (where possible), a cast like `int(var)` merely tells the compiler
to temporarily disregard the type of var and treat it as if it were an
int. In other words, it's a compiler instruction rather than a conversion
function.



--
Steven
From: John Nagle on
On 7/28/2010 7:32 AM, Steven D'Aprano wrote:
> On Wed, 28 Jul 2010 09:35:52 -0400, wheres pythonmonks wrote:
>
>> Thanks ... I thought int was a type-cast (like in C++) so I assumed I
>> couldn't reference it.
>
> Python doesn't have type-casts in the sense of "tell the compiler to
> treat object of type A as type B instead". The closest Python has to that
> is that if you have an instance of class A, you can do this:
>
> a = A() # make an instance of class A
> a.__class__ = B # tell it that it's now class B
>
> and hope that it won't explode when you try to use it :/
>
> I make that seem like a dangerous thing to do, but it's not really. There
> actually are sensible use-cases for such a thing, you can't do it to
> built-ins (which would be dangerous!), and the worst that will happen
> with classes written in Python is they'll raise an exception when you try
> calling a method, rather than dump core.

The main use for that sort of thing is in constructing objects
without their cooperation. "copy" and "pickle" do that,
as they build up objects without running their initializers.

Arguably, that would be better done with a built-in function for
creating arbitrary objects. Something like:

x = new_object("classname",
(("attr1", val1), ("attr2", val2)))

to create a new object in one atomic operation.
Storing into "__class__" may not be portable across
Python implementations. The implications for multiple
inheritance are difficult. It's really a hack for CPython.

John Nagle
From: Steven D'Aprano on
On Wed, 28 Jul 2010 22:45:19 -0700, John Nagle wrote:

[...]
>> if you have an instance of class A, you can do this:
>>
>> a = A() # make an instance of class A
>> a.__class__ = B # tell it that it's now class B
>>
>> and hope that it won't explode when you try to use it :/
[...]
> The main use for that sort of thing is in constructing objects
> without their cooperation. "copy" and "pickle" do that, as they build
> up objects without running their initializers.

True, but there are other use-cases as well, such as the recipe for ring
buffer which made it into the Python Cookbook. I think this is it:

http://code.activestate.com/recipes/68429-ring-buffer/


> Storing into "__class__"
> may not be portable across Python implementations. The implications for
> multiple inheritance are difficult. It's really a hack for CPython.

I believe that it is intended as a language feature, not an
implementation-specific hack:

http://bytes.com/topic/python/answers/449635-assigning-self-__class__


While it's an advanced technique that isn't terribly common, I don't see
any reason to avoid it.


--
Steven
From: Ulrich Eckhardt on
Steven D'Aprano wrote:
> Perhaps I have been misinformed, but my understanding of C type-casts is
> that (where possible), a cast like `int(var)` merely tells the compiler
> to temporarily disregard the type of var and treat it as if it were an
> int. In other words, it's a compiler instruction rather than a conversion
> function.

You are misinformed. The result of a cast in C or C++ behaves as if a
temporary was created:

int x = 0;
unsigned(x)--; // invalid, compiler error

Now, where this distinction gets blurred is when you are casting pointers:

(*(unsigned*)&x)--;

or, in C++, references:

reinterpret_cast<unsigned&>(x)--;

Technically, these are still invalid though, only that they give you
undefined behaviour at runtime instead of a compiler error, but those are
already very fine details of the according standards.


Uli

--
Sator Laser GmbH
Geschäftsführer: Thorsten Föcking, Amtsgericht Hamburg HR B62 932

From: Steven D'Aprano on
On Thu, 29 Jul 2010 09:21:37 +0200, Ulrich Eckhardt wrote:

> Steven D'Aprano wrote:
>> Perhaps I have been misinformed, but my understanding of C type-casts
>> is that (where possible), a cast like `int(var)` merely tells the
>> compiler to temporarily disregard the type of var and treat it as if it
>> were an int. In other words, it's a compiler instruction rather than a
>> conversion function.
>
> You are misinformed. The result of a cast in C or C++ behaves as if a
> temporary was created:

Fair enough. Thank you.




--
Steven