简体   繁体   English

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

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

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?如何在 Python 中动态创建该实例? thanks!谢谢!

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()

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 中使用字符串实例化一个类吗

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)

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 中,您可以只使用类本身。

You can use the python builtin eval() statement to instantiate your classes.您可以使用 python 内置eval()语句来实例化您的类。 Like this:像这样:

aa = eval(cName)()

Notice!注意!

using eval is dangerous and is a key for lots of security risks based on code injections.使用 eval 是危险的,并且是基于代码注入的许多安全风险的关键。

My problem was that I wanted to pass arguments into __init__ with the arguments being specified in a string on the command line.我的问题是我想将参数传递给__init__ ,参数是在命令行上的字符串中指定的。 For example, the equivalent of例如,相当于

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

The string on the command line is "abClassB.ClassB('World')"命令行上的字符串是"abClassB.ClassB('World')"

With the following class in module abClassB使用模块 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()

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/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM