在python中可以从字符串变量实例化类吗?

2024-04-23 14:17:49 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个字符串,其中包含一个有效的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__()加载它。还有其他(内存中的)解决方案吗?你知道吗

谢谢你的回答。你知道吗


Tags: 字符串nameselfaddreturnobjectinitis
1条回答
网友
1楼 · 发布于 2024-04-23 14:17:49

一位评论员提到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)

您可以通过直接调用^{}(函数string_to_class功能不够强大)来修复它,但是它很快就会变得非常棘手:我甚至还没有提到import的工作原理。还有其他技术(函数装饰器、元类)可以让你做你想做的事,但有时exec确实是你唯一的选择。你知道吗

相关问题 更多 >