programing

Python 변수의 유형을 확인하는 가장 좋은(자동) 방법은 무엇입니까?

randomtip 2022. 12. 11. 10:28
반응형

Python 변수의 유형을 확인하는 가장 좋은(자동) 방법은 무엇입니까?

Python의 변수가 문자열인지 딕트인지 알아야 합니다.아래 코드에 무슨 문제가 있나요?

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

업데이트: aviser의 답변을 수락했습니다(누군가 이유를 설명해주면 생각을 바꾸겠습니다만).isinstancetype(x) is를 참조해 주세요.

하지만 if/elif/else 시리즈보다 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

ifisinstance이 '는 게 좋을까요?value_list()능하하??? ???

만약 누군가가 당신의 함수에 유니코드 문자열을 전달한다면 어떻게 될까요?아니면 dict에서 파생된 수업?또는 dict와 같은 인터페이스를 구현하는 클래스?다음 코드는 처음 두 경우를 대상으로 합니다.Python 2.6을 사용하시는 경우, 대신 사용하실 수 있습니다.dictABC 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 좀 더 이 '타자'입니다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

Python의 빌트인 타입에는 다음과 같은 이름이 포함되어 있습니다.

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

는 연산자임을 주의해 주십시오.단, 유형 확인(이렇게 부르고 싶은 경우)은 보통 유형별 테스트를 try-except 절로 감싸서 수행합니다.이는 변수의 유형이 중요한 것이 아니라 변수를 사용하여 특정 작업을 수행할 수 있는지 여부이기 때문입니다.

isinstance는 오브젝트인스턴스와 슈퍼클래스를 비교할 때 True로 평가되기 때문에 유형보다 선호됩니다.이는 기본적으로 dict 또는 str 서브클래스와 함께 사용할 때 오래된 코드를 특별히 대문자와 소문자로 구분하지 않아도 된다는 것을 의미합니다.

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

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

물론, 여러분이 이런 행동을 원하지 않는 상황도 있을 수 있지만, 바라건대 그러한 상황은 여러분이 그것을 원하는 상황보다 훨씬 덜 흔합니다.

"오리처럼 걸으면 오리처럼 울부짖고, 오리처럼 울부짖는다"는 오리타자기 방식을 택할 생각입니다.이렇게 하면 문자열이 Unicode인지 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

동작합니다.따라서 코드에는 문제가 없습니다.그러나 다음과 같은 명령어를 사용하여 수행할 수도 있습니다.

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

좀 더 간결하고 비토닉하다고 하지 않겠어요?


편집... Aviser의 조언을 듣고 코드도 이렇게 작동하며 더 좋아 보입니다.

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

유형 검사를 수행하는 것이 좋습니다.http://pypi.python.org/pypi/typecheck

Python용 유형 검사 모듈

이 패키지는 Python 함수, 메서드 및 생성기를 위한 강력한 런타임 유형 검사 기능을 제공합니다.typecheck 패키지는 커스텀 프리프로세서나 언어의 변경을 필요로 하지 않고 프로그래머와 품질보증 엔지니어가 코드에 대한 입력 및 출력에 대해 정확한 어사션을 할 수 있도록 합니다.

저는 지금까지 다른 접근방식을 사용해 왔습니다.

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*

아니요, python에서 인수를 확인할 필요는 없습니다.그럴 필요 없어요.

코드가 문자열 또는 dict 객체를 받아들이면 설계가 중단됩니다.

그것은 당신이 당신의 프로그램에서 객체의 종류를 아직 알지 못한다면 당신은 이미 뭔가 잘못된 일을 하고 있다는 사실에서 비롯된다.

타이프 체크는 코드 재사용을 저해하고 성능을 저하시킵니다.전달된 오브젝트의 종류에 따라 다른 기능을 수행하는 것은 버그가 발생하기 쉽고, 이해 및 유지보수가 어려운 동작입니다.

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

1) 기능 만들기unique_values고유한 값 목록의 dits를 변환합니다.

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

전달된 인수가 항상 목록이라고 함수가 가정하도록 합니다.이렇게 함수에 문자열을 전달해야 할 경우 다음 작업을 수행합니다.

myfunction([some_string])

받아쓰기를 해야 할 경우 다음 작업을 수행합니다.

myfunction(unique_values(some_dict))

그것은 당신의 최선의 선택입니다.그것은 깨끗하고 이해하기 쉽고 유지보수가 용이합니다.코드를 읽는 사람은 누구나 무슨 일이 일어나고 있는지 즉시 알 수 있으며, 타이프 체크할 필요는 없습니다.

2) 문자열 목록을 받아들이는 기능과 받아 들이는 기능 두 가지를 만듭니다.1개의 콜을 가장 편리한 방법으로 다른 콜을 내부적으로 발신할 수 있습니다(myfunction_dict스트링과 콜의 리스트를 작성할 수 있습니다.myfunction_list).

어떤 경우에도 타이프 체크를 하지 마십시오.그것은 완전히 불필요하고 단점만 있다.대신 타입체크를 하지 않아도 되는 방법으로 코드를 리팩터링합니다.그렇게 함으로써 단기적으로나 장기적으로나 이익을 얻을 수 있습니다.

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

반응형