How to create a new instance from a class object in Python
I need to dynamically create an instance of a class in Python. Basically I am using the load_module and inspect module to import and load the class into a class object, but I can't figure out how to create an insta开发者_如何转开发nce of this class object.
I figured out the answer to the question I had that brought me to this page. Since no one has actually suggested the answer to my question, I thought I'd post it.
class k:
pass
a = k()
k2 = a.__class__
a2 = k2()
At this point, a and a2 are both instances of the same class (class k).
Just call the "type" built in using three parameters, like this:
ClassName = type("ClassName", (Base1, Base2,...), classdictionary)
update as stated in the comment bellow this is not the answer to this question at all. I will keep it undeleted, since there are hints some people get here trying to dynamically create classes - which is what the line above does.
To create an object of a class one has a reference too, as put in the accepted answer, one just have to call the class:
instance = ClassObject()
The mechanism for instantiation is thus:
Python does not use the new
keyword some languages use - instead it's data model explains the mechanism used to create an instantance of a class when it is called with the same syntax as any other callable:
Its class' __call__
method is invoked (in the case of a class, its class is the "metaclass" - which is usually the built-in type
). The normal behavior of this call is to invoke the (pseudo) static __new__
method on the class being instantiated, followed by its __init__
. The __new__
method is responsible for allocating memory and such, and normally is done by the __new__
of object
which is the class hierarchy root.
So calling ClassObject()
invokes ClassObject.__class__.call()
(which normally will be type.__call__
) this __call__
method will receive ClassObject itself as the first parameter - a Pure Python implementation would be like this: (the cPython version is of course, done in C, and with lots of extra code for cornercases and optimizations)
class type:
...
def __call__(cls, *args, **kw):
constructor = getattr(cls, "__new__")
instance = constructor(cls) if constructor is object.__new__ else constructor(cls, *args, **kw)
instance.__init__(cls, *args, **kw)
return instance
(I don't recall seeing on the docs the exact justification (or mechanism) for suppressing extra parameters to the root __new__
and passing it to other classes - but it is what happen "in real life" - if object.__new__
is called with any extra parameters it raises a type error - however, any custom implementation of a __new__
will get the extra parameters normally)
This is how you can dynamically create a class named Child
in your code, assuming Parent
already exists... even if you don't have an explicit Parent
class, you could use object
...
The code below defines __init__()
and then associates it with the class.
>>> child_name = "Child"
>>> child_parents = (Parent,)
>>> child body = """
def __init__(self, arg1):
# Initialization for the Child class
self.foo = do_something(arg1)
"""
>>> child_dict = {}
>>> exec(child_body, globals(), child_dict)
>>> childobj = type(child_name, child_parents, child_dict)
>>> childobj.__name__
'Child'
>>> childobj.__bases__
(<type 'object'>,)
>>> # Instantiating the new Child object...
>>> childinst = childobj()
>>> childinst
<__main__.Child object at 0x1c91710>
>>>
If you have a module with a class you want to import, you can do it like this.
module = __import__(filename)
instance = module.MyClass()
If you do not know what the class is named, you can iterate through the classes available from a module.
import inspect
module = __import__(filename)
for c in module.__dict__.values():
if inspect.isclass(c):
# You may need do some additional checking to ensure
# it's the class you want
instance = c()
If you have some class object, you can instantiate it by just calling it (with parenthesis).
class MyClass: pass
some_class = MyClass
some_instance = some_class() # -> instance of MyClass
I think the neat way would be using type
. Here is an example:
>>> class Foo:
... def __init__(self, s):
... self.s = s
...
>>> a = Foo("hello")
>>> a.s
'hello'
>>> b = type(a)("world")
>>> b.s
'world'
>>> assert isinstance(a, Foo)
>>> assert isinstance(b, Foo)
b
is an instance which has the same type as a
.
精彩评论