constructing an object from another instance of the same class

Bruno Desthuilliers bruno.42.desthuilliers at websiteburo.invalid
Fri Jun 18 08:25:20 EDT 2010


Christoph Groth a écrit :
> Dear all,
> 
> sometimes it is handy to have a function which can take as argument
> anything which can be converted into something, e.g.
> 
> def foo(arg):
>     arg = float(arg)
>     # ...
> 
> I would like to mimic this behavior of float for a user-defined type,
> e.g. 
> 
> def bar(arg):
>     arg = My_type(arg)
>     # ...
> 
> Now I wonder what is the most pythonic way to write the __init__ method
> of My_type?  The following comes to my mind:
> 
> class My_type:
>     def __init__(self, other):
>         if isinstance(other, type(self)):
>             self.a = other.a
>             self.b = other.b
>             return
>         # initialize self in some other way
> 
> It seems to me that in this way I might get problems when I pass an
> instance of Derived_from_my_type to bar, as it will become an instance
> of My_type.

The instance you pass to bar won't "become" anything else. You create a 
new My_type instance from the Derived_from_my_type one's values, and 
rebinding the _local_ name 'arg' only affects the local namespace.

<OT>
BTW, the convention in Python is to use TitleCase for class names 
(except - for historical reasons - for most builtin types which are 
lowercase).
</OT>

> What is a good way to express this?

Depends on what are the possible initializers / arguments for My_type. 
There are a few possible solutions but which one is best depends on the 
concrete case and personal tastes.

>  In C++ 

Forget about C++ - Python is a different beast !-)

>(which I know better than
> python) I would make bar accept a const reference to My_type.  Then I
> could use it directly with instances of My_type, Derived_from_my_type
> and other types which can be converted into My_type.

If you only worry about being able to use any "My_type like" object - 
that is, any object implementing a given subset of My_type's interface, 
then just document your expectations in the function's docstring and use 
whatever object is passed in as if it was a My_type instance. Period. As 
long as you document what your function expects, it's the caller's 
responsaibility to make sure it provides something compatible. If he 
don't, well he'll get a nice traceback.

I know this might look very freestyle and a bit frightening when coming 
from one of these B&D languages, but that's really the Python way, and 
from experience, it JustWork(tm).



More information about the Python-list mailing list