views:

60

answers:

1

Having a object x which is an instance of some class how to create a new instance of the same class as the x object, without importing that all possible classes in the same namespace in which we want to create a new object of the same type and using isinstance to figure out the correct type.

For example if x is a decimal number:

>>> from decimal import Decimal
>>> x = Decimal('3')
>>> x
Decimal('3')

how to create new instance of Decimal. I think the obvious thing to do would be either of these:

>>> type(x)('22')
Decimal('22')
>>> x.__class__('22')
Decimal('22')

Since __class__ will not work on int for example:

>>> 1.__class__
  File "<stdin>", line 1
    1.__class__

Is it good practice to use type to achieve this, or is there some other ways or more caveats when using this approach for creating new objects?

Note: There was an answer that is now deleted that gave a right way to get __class__ of int.

>>> (1).__class__
<type 'int'>

Use case

The question is mostly theoretical, but I am using this approach right now with Qt to create new instances of QEvent. For example, since the QEvent objects are consumed by the application event handler in order to post the event to QStateMachine you need to create a new instance of the event otherwise you get runtime error because the underlying C++ object get deleted.

And since I am using custom QEvent subclasses that all share the same base class thus objects accept same predefined set of arguments.

+3  A: 

Calling type(x) is definitely the canonical way to create a new instance of exactly the same type as x. However, what arguments to pass to that call is not a given, because the "signature" (number and types of arguments to pass in the call) changes with every different type; so, if you have no idea of what the type might be, you need more introspection for this purpose (as well as some rule or heuristic about what all arguments you want to pass once you've determined, for example, that you may pass any number from 0 to 3, and that the optional/keyword argument names are 'y', 'z', 't'... obviously it's impossible to establish a general rule here!).

So, can you please clarify (once the type to instantiate is, easily, determined;-) how you're going to be tackling the hard parts of your problem, that you don't even mention? What constraints can you assume on the type's signature? Do you need to perform some sanity checks on that or is it OK to just cause a TypeError by calling with the wrong kind or number of arguments? Etc, etc... without more info of this nature, your question just doesn't lend itself to proving an answer that can actually be used in the real world!-)

Alex Martelli
@Alex Martelli, thank you very much for you expert opinion and advice, the question is mostly theoretical but I have came across simple use case while dealing with Qt's `QEvent` (I have updated my question to reflect this).
rebus
@rebus, tx for clarifying!
Alex Martelli