【发布时间】:2018-08-11 20:52:10
【问题描述】:
我正在研究Advent of Code 2017 problems 以获得乐趣,其中一些要求您解释和执行伪汇编程序。我想编写一个重用模块,为此提供必要的基础设施。具体来说,我想提供沙盒化的 exec 和 eval 函数,以及解析解释命名空间中的变量的函数。我阅读了元类并开始构建一个,但我陷入了实现细节。我设想能够做到这一点:
class InterpreterMixinMeta(type):
"""see below for my attempt"""
pass
class InterpreterMixin(metaclass=InterpreterMixinMeta):
pass
class Program(InterpreterMixin):
"""does the actual work of running a pseudo-assembly program"""
pass
这是我在InterpreterMixinMeta 的初步尝试。如何在将使用 mixin 的对象上创建属性和方法?属性,例如 execs 和 evals 的本地字典的唯一副本,val() 等方法。
class InterpreterMixinMeta(type):
"""
A constructor for InterpreterMixin. Creates a new mixin class that
exposes functions needed for interpreting pseudo-assembly programs:
`execs`, `evals`, and `val`
"""
@staticmethod
def init_execs(exc_locals: dict):
"""Creates a persistent sandbox environment for calls to `exec`"""
sbox_globals = {'__builtins__': None}
def sbox_exec(source: str):
return exec(source, sbox_globals, exc_locals)
return sbox_exec
@staticmethod
def init_evals(exc_locals: dict):
"""Creates a persistent sandbox environment for calls to `eval`"""
sbox_globals = {'__builtins__': None}
def sbox_eval(expr: str):
return eval(expr, sbox_globals, exc_locals)
return sbox_eval
def val(self, x: str) -> str:
"""Returns the integer value of the input, formatted as a string"""
if x.isdigit():
return x
else:
return str(self.evals(x))
def __new__(mcs, name, bases, nspace):
# how do I let each object define a myLocals dict?
nspace['execs'] = InterpreterMixinMeta.init_execs(myLocals)
return super().__new__(mcs, name, bases, nspace)
【问题讨论】:
-
完全不清楚您是否需要一个元类:您是否尝试过仅使用继承?
-
不过,输入是可信的。该练习提供了伪代码,我的
program对象将其转换为由 mixin 中的evals和execs函数运行的硬编码 Python 语句。用户输入永远不会直接执行。至于元类的使用,我试图以这种方式解决问题,以便更多地了解元类的使用。毕竟,这只是一种爱好。为什么不通过实施来挑战自己? -
也许只是不要称它为“安全”,那么。使用元类可能不仅更难而且更丑:我怀疑你最终需要定义更多神奇的名字,比如
__slots__。 -
我将“安全”更改为“沙盒”以移除红鲱鱼。
-
我知道你在那里做了什么。
标签: python python-3.x metaclass