복붙노트

[PYTHON] 문자열에서 유형으로 어휘 캐스팅

PYTHON

문자열에서 유형으로 어휘 캐스팅

최근에 파이썬에서 파일의 정보를 저장하고 읽으려고 시도하면서 약간의 문제가 발생했습니다. 텍스트 파일에서 유형 정보를 읽고 싶었습니다. string에서 int 또는 float 로의 형 변환은 매우 효율적이지만, string에서 type으로의 형변환은 또 다른 문제점으로 보입니다. 당연히, 나는 이와 같은 것을 시도했다 :

var_type = type('int')

그러나 type은 캐스트가 아니라 변수의 유형을 찾기위한 메카니즘으로 사용됩니다. 실제로는 여기에 있습니다.

나는 그것을 할 수있는 방법을 찾았습니다 :

var_type = eval('int')

그러나 나는 일반적으로 eval이나 exec와 같은 함수 / 문장을 피하려고 노력한다. 그래서 내 질문은 다음과 같습니다 : 유형에 문자열을 던지기위한 또 다른 파이썬 (그리고 좀 더 구체적인) 방법이 있습니까?

해결법

  1. ==============================

    1.built-in 유형에서 작동하는 locate를 사용하는 것이 좋습니다.

    built-in 유형에서 작동하는 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>
    
  2. ==============================

    2.당신은 당신이하려고하는 것에 약간 혼란 스럽습니다. 타입 (클래스라고도 함)은 파이썬의 다른 모든 것과 마찬가지로 객체입니다. 프로그램에 int를 쓸 때 int라는 전역 변수를 참조하면 클래스가됩니다. 당신이하려는 것은 "문자열을 타입 변환"하는 것이 아니라 내장 변수를 이름으로 액세스하는 것입니다.

    당신은 당신이하려고하는 것에 약간 혼란 스럽습니다. 타입 (클래스라고도 함)은 파이썬의 다른 모든 것과 마찬가지로 객체입니다. 프로그램에 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)
    
  3. ==============================

    3.왜 룩업 테이블을 사용하지 않는가?

    왜 룩업 테이블을 사용하지 않는가?

    known_types = {
        'int': int,
        'float': float,
        'str': str
        # etc
    }
    
    var_type = known_types['int']
    
  4. ==============================

    4.아마도 이것이 여러분이 원하는 것일뿐입니다. 내장 타입 만 보입니다 :

    아마도 이것이 여러분이 원하는 것일뿐입니다. 내장 타입 만 보입니다 :

    def gettype(name):
        t = getattr(__builtins__, name)
        if isinstance(t, type):
            return t
        raise ValueError(name)
    
  5. from https://stackoverflow.com/questions/11775460/lexical-cast-from-string-to-type by cc-by-sa and MIT license