Lexical cast from string to type

前端 未结 4 999
粉色の甜心
粉色の甜心 2020-12-01 09:26

Recently, I was trying to store and read information from files in Python, and came across a slight problem: I wanted to read type information from text files. Type casting

相关标签:
4条回答
  • 2020-12-01 09:39

    Why not just use a look-up table?

    known_types = {
        'int': int,
        'float': float,
        'str': str
        # etc
    }
    
    var_type = known_types['int']
    
    0 讨论(0)
  • 2020-12-01 09:41

    I like using locate, which works on built-in types:

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

    ...as well as anything it can find in the path:

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

    ...including your custom types:

    >>> locate('mypackage.model.base.BaseModel')
    <class 'mypackage.model.base.BaseModel'>
    >>> m = locate('mypackage.model.base.BaseModel')
    >>> m()
    <mypackage.model.base.BaseModel object at 0x1099f6c10>
    
    0 讨论(0)
  • 2020-12-01 09:45

    You're a bit confused on what you're trying to do. Types, also known as classes, are objects, like everything else in python. When you write int in your programs, you're referencing a global variable called int which happens to be a class. What you're trying to do is not "cast string to type", it's accessing builtin variables by name.

    Once you understand that, the solution is easy to see:

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

    If you really wanted to turn a type name into a type object, here's how you'd do it. I use deque to do a breadth-first tree traversal without recursion.

    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)
    
    0 讨论(0)
  • 2020-12-01 10:03

    Perhaps this is what you want, it looks into builtin types only:

    def gettype(name):
        t = getattr(__builtins__, name)
        if isinstance(t, type):
            return t
        raise ValueError(name)
    
    0 讨论(0)
提交回复
热议问题