如何在python中动态创建类的实例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3451779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:09:20  来源:igfitidea点击:

how to dynamically create an instance of a class in python?

python

提问by Nyambaa

I have list of class names and want to create their instances dynamically. for example:

我有类名列表并希望动态创建它们的实例。例如:

names=[
'foo.baa.a',
'foo.daa.c',
'foo.AA',
 ....
]

def save(cName, argument):
 aa = create_instance(cName) # how to do it?
 aa.save(argument)

save(random_from(names), arg)

How to dynamically create that instances in Python? thanks!

如何在 Python 中动态创建该实例?谢谢!

采纳答案by Scott Lance

This is often referred to as reflection or sometimes introspection. Check out a similar questions that have an answer for what you are trying to do:

这通常被称为反思,有时也称为自省。查看一个类似的问题,这些问题对您正在尝试做的事情有答案:

Does Python Have An Equivalent to Java Class forname

Python 是否有等效于 Java 的类 forname

Can You Use a String to Instantiate a Class in Python

你能在 Python 中使用字符串实例化一个类吗

回答by hb2pencil

You can use the python builtin eval()statement to instantiate your classes. Like this:

您可以使用 python 内置eval()语句来实例化您的类。像这样:

aa = eval(cName)()

Notice!

注意!

using eval is dangerous and is a key for lots of security risks based on code injections.

使用 eval 是危险的,并且是基于代码注入的许多安全风险的关键。

回答by S.Lott

You can often avoid the string processing part of this entirely.

您通常可以完全避免字符串处理部分。

import foo.baa 
import foo.AA
import foo

classes = [ foo.baa.a, foo.daa.c, foo.AA ]

def save(theClass, argument):
   aa = theClass()
   aa.save(argument)

save(random.choice(classes), arg)

Note that we don't use a string representation of the name of the class.

请注意,我们不使用类名称的字符串表示形式。

In Python, you can just use the class itself.

在 Python 中,您可以只使用类本身。

回答by elewinso

Assuming you have already imported the relevant classes using something like

假设您已经使用类似的方法导入了相关类

from [app].models import *

all you will need to do is

你需要做的就是

klass = globals()["class_name"]
instance = klass()

回答by Tobias Ernst

This worked for me:

这对我有用:

from importlib import import_module

class_str: str = 'A.B.YourClass'
try:
    module_path, class_name = class_str.rsplit('.', 1)
    module = import_module(module_path)
    return getattr(module, class_name)
except (ImportError, AttributeError) as e:
    raise ImportError(class_str)

回答by Nic

Best Answer I found: Better Way is to make a dictionary: objects ={} Names =[object1,object2, object3]

我找到的最佳答案:更好的方法是制作字典:objects ={} Names =[object1,object2, object3]

For objname in Names: objects[objname]=classname()

对于名称中的 objname:objects[objname]=classname()

Found in: https://www.thecodingforums.com/threads/create-object-name-from-string-value.712461/

发现于:https: //www.thecodingforums.com/threads/create-object-name-from-string-value.712461/

回答by David Wood

My problem was that I wanted to pass arguments into __init__with the arguments being specified in a string on the command line. For example, the equivalent of

我的问题是我想将参数传递__init__给在命令行上的字符串中指定的参数。例如,相当于

import a.b.ClassB as ClassB
instance = ClassB.ClassB('World')

The string on the command line is "a.b.ClassB.ClassB('World')"

命令行上的字符串是 "a.b.ClassB.ClassB('World')"

With the following class in module a.b.ClassB

使用模块 abClassB 中的以下类

class ClassB():

    def __init__(self, name:str):
        self._name = name

    def hello(self):
        print("Hello " + self._name + "!")

we can create this class with the following

我们可以使用以下内容创建这个类

import importlib

def create_instance(class_str:str):
    """
    Create a class instance from a full path to a class constructor
    :param class_str: module name plus '.' plus class name and optional parens with arguments for the class's
        __init__() method. For example, "a.b.ClassB.ClassB('World')"
    :return: an instance of the class specified.
    """
    try:
        if "(" in class_str:
            full_class_name, args = class_name = class_str.rsplit('(', 1)
            args = '(' + args
        else:
            full_class_name = class_str
            args = ()
        # Get the class object
        module_path, _, class_name = full_class_name.rpartition('.')
        mod = importlib.import_module(module_path)
        klazz = getattr(mod, class_name)
        # Alias the the class so its constructor can be called, see the following link.
        # See https://www.programiz.com/python-programming/methods/built-in/eval
        alias = class_name + "Alias"
        instance = eval(alias + args, { alias: klazz})
        return instance
    except (ImportError, AttributeError) as e:
        raise ImportError(class_str)

if __name__ == "__main__":
    instance = create_instance("a.b.ClassB.ClassB('World')")
    instance.hello()