Python 2.7 从内置类型的字符串名称创建(实例化?)对其的引用

Python 2.7 从内置类型的字符串名称创建(实例化?)对其的引用,python-2.7,pyyaml,voluptuous,Python 2.7,Pyyaml,Voluptuous,我希望能够在yaml中定义一个模式,使用pyyaml阅读它,然后使用voluputous(或其他模式验证器!)进行验证。然而,正如问题标题中所述,我遇到了为Volupturous实例化内置类str的需要,而不是它的字符串表示 from voluptuous import Schema import yaml y = ''' a: str b: int c: d: float e: str ''' yaml_schema = yaml.load(y,

我希望能够在yaml中定义一个模式,使用
pyyaml
阅读它,然后使用
voluputous
(或其他模式验证器!)进行验证。然而,正如问题标题中所述,我遇到了为Volupturous实例化内置类
str
的需要,而不是它的字符串表示

from voluptuous import Schema
import yaml


y = '''
a: str
b: int
c:
  d: float
  e: str
'''

yaml_schema = yaml.load(y,
                        Loader=yaml.CLoader)

schema1 = Schema(yaml_schema, required=True)
但是,这个模式现在正在寻找字符串
str
作为
a
的唯一可接受值。使用直接pyyaml(例如'a':!!python/int)失败。相反,我想要下面的模式:

schema2 = Schema({'a': str,
                 'b': int,
                 'c': {'d': float,
                       'e': str}},
                required=True)
我很清楚
eval
不是生产解决方案,但是下面的函数
evaler
schema1
转换为
schema2

def evaler(d):
    out = {}
    for k, v in d.items():
        if isinstance(v, dict):
            out[k] = evaler(v)
        else:
            out[k] = eval(v)
    return out


我还知道可以实例化一个空类:

class foo: pass
globals()['foo']
但对于内置设备,这是不可能的:

globals()['int']
# KeyError: 'int'

我探索了
新的
类型
模块,但没有任何运气…

最安全、最简单、最清晰的解决方案是明确列出您关心的类型的映射:

TYPES = {
    'str': str,
    'int': int,
    ...
}
通过从类型列表中创建此dict,您可以消除重复(以牺牲一些灵活性为代价):

TYPES = {cls.__name__: cls for cls in [str, int, ...]}
然后可以递归地遍历文档(就像在
evaler
中所做的那样),并用
类型替换每个字符串。
如果您坚持按名称支持所有内置类型,而不单独列出它们,则可以使用
内置模块(在Python 2中称为
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
)。
getattr
是您的朋友。您可能应该检查它是否是一种类型——有许多内置名称不是


在任何情况下都需要遍历文档。从PyYAML的角度来看,用作映射值的字符串“str”与用作映射键的字符串“a”具有相同的标记,因此不能通过为该标记指定不同的类来执行任何操作。虽然您可能会深入研究它的本质,引入一种以不同方式对待标量映射值的方法,但这只是一种方法:一种方法。还有大量的额外工作要启动。不值得。

谢谢,请参阅我对第二个答案的评论。有没有办法通过
pyyaml
中提供的工具来避免文档的完整浏览和替换?太好了,谢谢!为了安全起见,我想我要走那种类型的路线。
TYPES = {cls.__name__: cls for cls in [str, int, ...]}