Maison  >  Questions et réponses  >  le corps du texte

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

问题的描述

现在有一个需求,就是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
我的需求就是,定义一个模块,在这个模块的函数中执行一段指定的字符串,动态定义一个类,并且需要调用这个类,现在遇到的问题如上所示,求助啊。。。

ringa_leeringa_lee2764 Il y a quelques jours607

répondre à tous(2)je répondrai

  • 天蓬老师

    天蓬老师2017-04-18 10:07:37

    Tout d'abord, "exec" n'est pas une méthode recommandée car elle posera quelques problèmes :

    • Certains modules basés sur l'attribut __module__ échoueront, comme pickle, inspect, pydoc, etc.

    • Fuite de mémoire

    • Problème de comportement d'arrêt de l'espace de noms et du module

    Pour une description détaillée de ces problèmes, veuillez vous référer à : http://lucumr.pocoo.org/2011/...

    Si vous insistez pour le faire, le code suivant peut fournir une référence :

    • testeur.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
    • acteur.py

    # encoding: utf-8
    # actor.py
    
    def execute(content, m_globals, m_locals):
        exec(content, m_globals, m_locals)
        return m_globals['do']()

    répondre
    0
  • 大家讲道理

    大家讲道理2017-04-18 10:07:37

    Créer dynamiquement une classe

    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

    Vous envisageriez d'utiliser exec, peut-être parce que vous n'êtes pas exposé aux fonctionnalités avancées de python

    répondre
    0
  • Annulerrépondre