从字符串到类型的词法转换

2024-06-16 13:17:01 发布

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

最近,我试图用Python存储和读取文件中的信息,但遇到了一个小问题:我想从文本文件中读取类型信息。从字符串到int或到float的类型转换非常有效,但是从字符串到类型的类型转换似乎是另一个问题。当然,我试过这样的方法:

var_type = type('int')

但是,type不是用作转换,而是用作查找变量类型的机制,实际上这里是str

我找到了一个办法:

var_type = eval('int')

但我通常尽量避免像evalexec这样的函数/语句。所以我的问题是:有没有另一种pythonic(更具体的)方法将字符串转换为类型?


Tags: 文件方法字符串信息类型vartypeeval
3条回答

为什么不直接用一张查找表呢?

known_types = {
    'int': int,
    'float': float,
    'str': str
    # etc
}

var_type = known_types['int']

你有点搞不懂你想做什么。类型,也称为类,与python中的其他类型一样,都是对象。在程序中编写int时,引用的是一个名为int的全局变量,它恰好是一个类。您要做的不是“将字符串转换为类型”,而是按名称访问内置变量。

一旦你明白了这一点,解决方案就很容易看到:

def get_builtin(name):
    return getattr(__builtins__, name)

如果你真的想把一个类型名变成一个类型对象,你可以这样做。我使用deque来进行不带递归的广度优先树遍历。

def gettype(name):
    from collections import deque
    # q is short for "queue", here
    q = deque([object])
    while q:
        t = q.popleft()
        if t.__name__ == name:
            return t
        else:
            print 'not', t

        try:
            # Keep looking!
            q.extend(t.__subclasses__())
        except TypeError:
            # type.__subclasses__ needs an argument, for whatever reason.
            if t is type:
                continue
            else:
                raise
    else:
        raise ValueError('No such type: %r' % name)

我喜欢使用locate,它在内置类型上工作:

>>> from pydoc import locate
>>> locate('int')
<type 'int'>
>>> t = locate('int')
>>> t('1')
1

…以及它在路上能找到的任何东西:

>>> locate('datetime.date')
<type 'datetime.date'>
>>> d = locate('datetime.date')
>>> d(2015, 4, 23)
datetime.date(2015, 4, 23)

…包括自定义类型:

>>> locate('mypackage.model.base.BaseModel')
<class 'mypackage.model.base.BaseModel'>
>>> m = locate('mypackage.model.base.BaseModel')
>>> m()
<mypackage.model.base.BaseModel object at 0x1099f6c10>

相关问题 更多 >