development

파이썬 변수의 유형을 확인하는 가장 좋은 방법은 무엇입니까?

big-blog 2020. 3. 18. 08:09
반응형

파이썬 변수의 유형을 확인하는 가장 좋은 방법은 무엇입니까? [복제]


이 질문에는 이미 답변이 있습니다.

파이썬의 변수가 문자열인지 dict인지 알아야합니다. 다음 코드에 문제가 있습니까?

if type(x) == type(str()):
    do_something_with_a_string(x)
elif type(x) == type(dict()):
    do_somethting_with_a_dict(x)
else:
    raise ValueError

업데이트 : 나는 avisser의 대답을 받아 들였습니다 (왜 누군가가 왜 isinstance선호 하는지 설명하면 마음이 바뀔 것입니다 type(x) is).

그러나 if / elif / else 시리즈보다 dict (사례 진술로)을 사용하는 것이 더 깨끗하다는 것을 상기시켜 준 nakedfanatic에게 감사합니다.

사용 사례를 자세히 설명하겠습니다. 변수가 문자열이면 목록에 넣어야합니다. 그것이 dict이면 고유 값 목록이 필요합니다. 내가 생각해 낸 것은 다음과 같습니다.

def value_list(x):
    cases = {str: lambda t: [t],
             dict: lambda t: list(set(t.values()))}
    try:
        return cases[type(x)](x)
    except KeyError:
        return None

경우 isinstance바람직하고, 당신은 어떻게이 작성합니다 value_list()기능을?


누군가 유니 코드 문자열을 함수에 전달하면 어떻게됩니까? 아니면 dict에서 파생 된 수업? 아니면 dict-like 인터페이스를 구현하는 클래스? 다음 코드는 처음 두 가지 경우를 다룹니다. Python 2.6을 사용 collections.Mapping하는 dict경우 ABC PEP 대신 대신 사용할 수 있습니다 .

def value_list(x):
    if isinstance(x, dict):
        return list(set(x.values()))
    elif isinstance(x, basestring):
        return [x]
    else:
        return None

type(dict())"새로운 dict을 만들고 그 유형이 무엇인지 알아 내십시오"라고 말합니다. 그냥 말하는 것이 더 빠릅니다 dict. 그러나 유형을 확인하려면 더 관용적 인 방법입니다 isinstance(x, dict).

참고 isinstance또한 서브 클래스 (감사 포함 더스틴를 )

class D(dict):
    pass

d = D()
print("type(d) is dict", type(d) is dict)  # -> False
print("isinstance (d, dict)", isinstance(d, dict))  # -> True

파이썬의 내장 타입은 내장 된 이름을 가지고 있습니다 :

>>> s = "hallo"
>>> type(s) is str
True
>>> s = {}
>>> type(s) is dict
True

btw는 is 연산자입니다. 그러나 유형 검사 (당신이 그것을 원한다면)는 일반적으로 try-except 절에 유형별 테스트를 배치하여 수행됩니다. 중요한 변수의 유형은 아니지만 특정 작업을 수행 할 수 있는지 여부 그것으로 또는 아닙니다.


isinstance는 객체 인스턴스를 수퍼 클래스와 비교할 때 True로 평가되기 때문에 유형보다 선호됩니다. 기본적으로 dict 또는 str 서브 클래스와 함께 사용하기 위해 이전 코드를 특수하게 처리 할 필요가 없습니다.

예를 들면 다음과 같습니다.

 >>> class a_dict(dict):
 ...     pass
 ... 
 >>> type(a_dict()) == type(dict())
 False
 >>> isinstance(a_dict(), dict)
 True
 >>> 

물론,이 행동을 원하지 않는 상황이있을 수도 있지만, 원하는 상황보다 훨씬 덜 일반적입니다.


오리 타이핑 방식으로 갈 것입니다. "오리처럼 걷는다면 오리처럼 오리처럼 떨립니다." 이렇게하면 문자열이 유니 코드 또는 ASCII인지 걱정할 필요가 없습니다.

내가 할 일은 다음과 같습니다.

In [53]: s='somestring'

In [54]: u=u'someunicodestring'

In [55]: d={}

In [56]: for each in s,u,d:
    if hasattr(each, 'keys'):
        print list(set(each.values()))
    elif hasattr(each, 'lower'):
        print [each]
    else:
        print "error"
   ....:         
   ....:         
['somestring']
[u'someunicodestring']
[]

여기 전문가들은이 유형의 덕 타이핑 사용법에 대해 의견을 환영합니다.이를 사용하고 있지만 최근에 정확한 개념을 소개했으며 매우 흥분했습니다. 그래서 나는 그것이 과잉 행동인지 알고 싶습니다.


실제로하는 것이 좋을 것 같아요

if isinstance(x, str):
    do_something_with_a_string(x)
elif isinstance(x, dict):
    do_somethting_with_a_dict(x)
else:
    raise ValueError

2 코드에 따라 다른 형식이 아마도 그보다 더 나은 것으로 간주됩니다. 하나는 도약하기 전에 보지 않는 것입니다

try:
  one, two = tupleOrValue
except TypeError:
  one = tupleOrValue
  two = None

다른 방법은 Guido에서 왔으며 함수 오버로드 형식으로 코드를 더 개방적으로 남겨 둡니다.

http://www.artima.com/weblogs/viewpost.jsp?thread=155514


작동해야합니다. 그래서 코드에는 아무런 문제가 없습니다. 그러나 dict으로도 수행 할 수 있습니다.

{type(str()): do_something_with_a_string,
 type(dict()): do_something_with_a_dict}.get(type(x), errorhandler)()

좀 더 간결하고 pythonic 말하지 않습니까?


편집 .. Avisser의 조언에주의를 기울이면 코드도 다음과 같이 작동하며 더 좋아 보입니다.

{str: do_something_with_a_string,
 dict: do_something_with_a_dict}.get(type(x), errorhandler)()

typecheck를 확인하고 싶을 수도 있습니다. http://pypi.python.org/pypi/typecheck

파이썬 타입 검사 모듈

이 패키지는 Python 함수, 메소드 및 생성기에 강력한 런타임 유형 검사 기능을 제공합니다. 사용자 정의 전 처리기 또는 언어 변경없이 타입 체크 패키지를 사용하면 프로그래머와 품질 보증 엔지니어가 코드 입력 및 출력에 대한 정확한 주장을 할 수 있습니다.


나는 다른 접근법을 사용하고 있습니다 :

from inspect import getmro
if (type([]) in getmro(obj.__class__)):
    # This is a list, or a subclass of...
elif (type{}) in getmro(obj.__class__)):
    # This one is a dict, or ...

그래도 왜 내가 왜 이것을 대신 사용했는지 기억이 안납니다.


*sigh*

아니요, 파이썬에서 인수를 타입 확인하는 것은 필요하지 않습니다. 그것은 없다 결코 필요.

코드가 문자열이나 dict 객체를 받아들이면 디자인이 깨집니다.

그것은 자신의 프로그램에서 객체의 유형을 이미 모른다면 이미 무언가 잘못하고 있다는 사실에서 비롯됩니다.

유형 검사는 코드 재사용을 손상시키고 성능을 저하시킵니다. 전달 된 객체의 유형에 따라 다른 작업을 수행하는 기능을 갖는 것은 버그가 발생하기 쉽고 이해하고 유지하기 어려운 동작을합니다.

다음과 같은 saner 옵션이 있습니다.

1) unique_values고유 한 값 목록에서 dicts를 변환 하는 함수 를 작성하십시오.

def unique_values(some_dict):
    return list(set(some_dict.values()))

함수가 전달 된 인수가 항상 목록이라고 가정하십시오. 이렇게하면 문자열을 함수에 전달 해야하는 경우 다음을 수행하십시오.

myfunction([some_string])

그것을 받아 들여야 할 경우 다음을 수행하십시오.

myfunction(unique_values(some_dict))

이것이 최선의 선택이며 깨끗하고 이해하기 쉽고 유지 관리하기 쉽습니다. 코드를 읽는 사람은 무슨 일이 일어나고 있는지 즉시 이해하므로 타입 검사를하지 않아도됩니다.

2) 두 개의 기능을 만드십시오. 하나는 문자열 목록을 허용하고 다른 하나는 dicts를 허용합니다. 가장 편리한 방법으로 하나의 내부에서 다른 전화를 걸 수 있습니다 ( myfunction_dict문자열 목록을 작성하고을 호출 할 수 있음 myfunction_list).

어쨌든 typecheck을 입력하지 마십시오 . 완전히 불필요하며 단점 만 있습니다. 타이핑 할 필요가없는 방식으로 코드를 리팩터링하십시오. 단기적으로나 장기적으로 만 혜택을 얻을 수 있습니다.

참고 URL : https://stackoverflow.com/questions/378927/what-is-the-best-idiomatic-way-to-check-the-type-of-a-python-variable

반응형