tags:

views:

100

answers:

2

I wrote a function in Python:

def instantiate(c):
    if inspect.isclass(c): return c()
    elif isinstance(c, object): return c
    else: raise Exception, '%s is not an object or class.' % c

Now I want to do the opposite: get the class from an already instantiated object so that I can re-instantiate it with different parameters. How can I do that?


Tests:

>>> f = Form()
>>> type(f)()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: instance() takes at least 1 argument (0 given)
>>> f.__class__()
<forms.Form instance at 0xb7f4d5cc>

More tests:

>>> o = object()
>>> type(o)()
<object object at 0xb7f78478>
>>> o.__class__()
<object object at 0xb7f78480>

Seems to work for object but not my Form class:

class Form:
    def __init__(self, data={}, prefix='', action='', id=None):

I'm guessing this has something to do with self but I don't know what.

+4  A: 

To get the class of x

x.__class__
gnibbler
`x.__class__()` seems to work. Thanks!
Mark
+1  A: 

The class of object c is type(c).

Alex Martelli
No. That tells me what class `c` is, but doesn't let me re-instantiate it.
Mark
@Mark, try this type(c)()
Anurag Uniyal
Yes. It very much does. Try it and see.
jemfinch
@Mark, you said, and I quote, "get the class". Instantiating it, **of course**, means _calling_ it -- how else do you thing you **ever** instantiate any type or class in Python, except by calling it?! I notice you had no problem understanding you needed to _call_ the class (or type, same thing) in your comment on @gnibbler's response (which I consider inferior simply because `.__class__` is so much longer than `type()`!), while for me you only had a downvote -- OK, duly noticed.
Alex Martelli
@Alex: Don't take so much offense! I *did* try it exactly like Anurag suggested. See my updated question. I down-voted you because I assumed you didn't read past "get the class" and missed the part about "so that I can re-instantiate it". If you did read the question fully, and thought that this would work, or perhaps I'm doing something wrong, then I apologize.
Mark
`type(c)` doesn't work for old style classes
gnibbler
@gnibbler, true -- one more excellent reason to avoid old-style classes.
Alex Martelli
I'd +1 you *now*, but I can't ;)
Mark