我想在python用exec动态执行某些语句,动态定义一个类并随后调用这个类,但是出现了问题。

发布于 2022-09-04 08:05:21 字数 1024 浏览 15 评论 0

问题的描述

现在有一个需求,就是python中使用字符串动态定义一个类,并随后使用其中的方法。

可以运行的代码

# /test.py
# coding=utf-8

content = '''
class MyClass:
    def __init__(self):
        self.name = None
        self.age = None
def do():
    return MyClass()
'''

exec content
print do()
# 或者最后一句话改成exec("print do()")

直接运行这段代码是没有问题的,得到了输出<__main__.MyClass instance at 0x000000000243EB88>

不可以运行的代码

首先定义另一个actor.py文件:

# /actor.py
# coding=utf-8

def execute(content):
    exec content
    return do()

然后定义test.py文件:

# /test.py
# coding=utf-8

import actor

content = """
class MyClass:
    def __init__(self):
        self.name = None
        self.age = None
def do():
    return MyClass()
"""
print actor.execute(content)

运行test.py文件,会出现NameError: global name 'MyClass' is not defined
我的需求就是,定义一个模块,在这个模块的函数中执行一段指定的字符串,动态定义一个类,并且需要调用这个类,现在遇到的问题如上所示,求助啊。。。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨落成白 2022-09-11 08:05:21

首先“exec”是不被推荐的方法,因为它会带来一些问题:

  • 一些基于__module__属性的模块会失败,比如pickle,inspect,pydoc等

  • 内存泄漏

  • namespace和module shutdown behavior issue

关于这几点问题的详细描述,可以参考:http://lucumr.pocoo.org/2011/...

既然你硬要这么做的话,下面代码可以提供一点参考:

  • tester.py

# encoding: utf-8
# tester.py

import actor

content = """
class MyClass:
    def __init__(self):
        self.name = None
        self.age = None

def do():
    return MyClass()
"""

vars = {}
code = compile(content, '<string>', 'exec')
m_cls = actor.execute(code, vars, vars)
print m_cls.name
  • actor.py

# encoding: utf-8
# actor.py

def execute(content, m_globals, m_locals):
    exec(content, m_globals, m_locals)
    return m_globals['do']()
柠檬色的秋千 2022-09-11 08:05:21

动态创建一个类

def init(self, name):
    self.name = name

attrs = dict(name=None, age=None, __init__=init )
# type创建一个类, base object, 设置属性和__init__等
klass = type("MyClass", (object, ), attrs)

my = klass(name="Hello")

print(my)       # <__main__.MyClass object at 0x10b882290>
print(my.name)  # Hello

你会考虑用exec, 可能是没接触到python的高级特性

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文