是否可以从 python 中的字符串变量实例化一个类?

Posted

技术标签:

【中文标题】是否可以从 python 中的字符串变量实例化一个类?【英文标题】:Is it possible to instantiate a class from a string variable in python? 【发布时间】:2019-06-13 04:34:25 【问题描述】:

假设我有一个包含有效 python 类(不是类名)的字符串。例如:

class_template = """
class MyClass(object):
    def __init__(self, name):
         self.name = name

    def print_name(self):
        print('My name is: ' + self.name)

    def add_whatever(a, b):
        return a + b
"""

是否可以在 python 中实现一个函数(在下面的示例中为string_to_class),它接收这个字符串并从中创建一个 python 类,以便我以后可以实例化该类?

class_template = """
class MyClass(object):
    def __init__(self, name):
         self.name = name

    def print_name(self):
        print('My name is: ' + self.name)

    def add_whatever(a, b):
        return a + b
"""

MyClass = string_to_class(class_template)
my_class_instance = MyClass('Ben')

print(MyClass.add_whatever(2, 3))
my_class_instance.print_name()

输出应该是:

5
My name is: Ben

一种可能的解决方案是将字符串写入MyClass.py 文件并使用__import__() 加载它。还有其他(内存中的)解决方案吗?

谢谢你的回答。

【问题讨论】:

我提出 x/y 问题:为什么你想这样做?您有几个特征听起来像是问题背后的系统设计不雅。 你可以查看eval函数族,但我们先看看是否存在设计缺陷。 您可以为此使用exec(这实际上是namedtuple 所做的,或在某些时候所做的)。 @Prune 我不想这样做。我只是对 python 的功能感兴趣。就这样。感谢您的回答。 @juanpa.arrivillaga 谢谢。 【参考方案1】:

一位评论者提到了exec;这就是你将它们组合在一起的方式:

def string_to_class(python_text):
    local_vars = 
    exec(python_text, , local_vars)
    # assume just a single new symbol was created (the class), and return it
    return list(local_vars.values())[0]

class_template = """
class MyClass(object):
    def __init__(self, name):
         self.name = name

    def print_name(self):
        print('My name is: ' + self.name)

    @staticmethod
    def add_whatever(a, b):
        return a + b
"""

MyClass = string_to_class(class_template)
my_class_instance = MyClass('Ben')

print(MyClass.add_whatever(2, 3))
my_class_instance.print_name()

但就像其他一些评论者提到的那样,这不是一种常用的技术,所以要小心。随着用例变得越来越复杂,您也会很快遇到问题:

some_string_that_defines_a_base_class = "case Base..."
some_string_that_defines_a_derived_class = "case Derived(Base):..."

Base = string_to_class(some_string_that_defines_a_base_class)
# this will crash because Base isn't defined in the scope that the string
# is being evaluated with
Derived = string_to_class(some_string_that_defines_a_derived_class)

您可以通过直接调用 exec 来修复它(string_to_class 函数根本不够强大),但它很快就会变得非常难以使用:我什至没有提到 imports 是如何工作的然而。还有其他技术(函数装饰器、元类)可以让你做你想做的事,减少痛苦,但有时exec 确实是你唯一的选择。

【讨论】:

这正是我想要的。谢谢。

以上是关于是否可以从 python 中的字符串变量实例化一个类?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JavaScript 中从字符串实例化一个类

python如何用字符串实例化类

Python

python 基础

python面向对象中类对象实例对象类变量实例变量类方法实例方法静态方法

Python面向对象---类的基本使用