확인할 수 있는 최선의 방법은 인수만 파이썬 함수

39 의 확인할 수 있는 효율적인 방법을 찾고, m i& com/go/4e6b330a_kr 파이썬 함수. 예를 들어, I& # 39; d like to check 인수만 유형 및 가치. 모듈에서는 엔드입니다 있나요? 또는, 또는 특정 관용구 데코레이터 같은 항목을 활용해야 합니까?

def my_function(a, b, c):
    """an example function I'd like to check the arguments of."""
    # check that a is an int
    # check that 0 < b < 10
    # check that c is not an empty string

파이썬 3.x-specific 기반으로 한, 우리는 이 길게 오토메이티드 구현하십시오 유형 검사를 데코레이터 [PEP 484] (https://www.python.org/dev/peps/pep-0484) 에서 힌트를 줄 순수 파이썬 유형 등에 미만임 275 (대부분 원하는거요 닥스트링스 설명 및 주석) - 심하게 최적화된 갖춰진 강력한 실제 활용 가능한 모든 모서리까지 제어됨을 test suite (https://github.com/pytest-dev/pytest) ['피오트레스트'] 틀린 건.

  • 곰이 의 feast on the 예상치 못한 멋진 입력 *:
>>> @beartype
... def spirit_bear(kermode: str, gitgaata: (str, int)) -> tuple:
...     return (kermode, gitgaata, "Moksgm'ol", 'Ursus americanus kermodei')
>>> spirit_bear(0xdeadbeef, 'People of the Cane')
AssertionError: parameter kermode=0xdeadbeef not of 

이런 예는 명시적으로 타입 검사 및 반환 값 입력하면 주석을 단 것으로, 곰 제안됩니다 up1 매개 변수 튜플을 단순한 유형이거나 이러한 유형. _을 _golly!

39 의 that& o. K., 실제로 인상적. '모든' 와 파이썬 3.x-specific @beartype other 데코레이터 유형 검사를 토대로 [PEP 484] (https://www.python.org/dev/peps/pep-0484) 에서 힌트를 유형 등에 미만임 275 줄의 순수 파이썬. 그래서 what& s # 39, 장애, bub?

순결케 브루시포스 하드코어 효율성

이 모든 것보다 훨씬 더 많은 짐을 모두 효율적인 공간과 시간을 기존 구현을 문자 입력 체크 인을 Python 을 best of my 제한된 분야 전문 지식을. (More later. 있는)

39 의 파이썬, 그러나, 일반적으로 doesn& 효율성 문제가 없다. # 39, t 를 사용할 경우, 당신은 wouldn& 아니하였으매 파이썬. 실제로 이것이 아직 최적화) 를 벗어난 안정된 유형 검사를 높여줍니까 피할 수 있다. 그렇습네다. Yes, it does.

관심 있는 오버헤드에 자도으로 프로필링 고려해보십시오 어쩔 수 없이 각 프로파일링된 메트릭은 (예를 들면, 함수 호출, 선). C 확장을 통해 정확한 결과를 얻을 수 있도록 이 오버헤드는 완화됨 최적화합니다 (예: '뒤에' 'C' 모듈에서는 활용할 확장명은 _lsprof 크프로피레) 보다는 최적화되지않은 순수 파이썬 (예: '프로파일할' 모듈에서는). 정말 does 프로파일하는 경우에는 효율성 해도 과언이 아니다. 유형 검사를 다르지 않다. 각 응용 프로그램에 자도으로 유형 검사를 오버헤드에 함수 호출 유형 중 가장 이상적인 all 저들이요 검토자 - 일반 막기 위해 직장 동료 (단, 안타깝게도 도량이 좁은) 에서 분리, s 타입 검사 후 추가된 # 39 마지막 Friday& 너회가 자동으로 데이터베이스에구성원을 노인 카페인 썩은 앨 리터 웹 애플리케이션 (앱) 을 너무 빨라서 fast. 합니다 유형 검사 구형 장고 it& 추가할 때 어느 누구도 공지 # 39 의 물어보지도 않고 있습니다. 이렇게 I &lt, sup&gt, 항상! 이 경우 정지점을 판독값 coworker.&lt /sup>; 심지어 쑥스러운 경우 응용 프로그램, 그러나, 곰, t # 39 를 게걸 들린 단축시킵니다 isn& 속도용 충분히 있을 수 있으므로 전역으로라는 비활성화됨 파이썬 최적화 (예를 들어, '-O' 를 전달하여 옵션을 파이썬 인터프리터):

$ python3 -O
# This succeeds only when type checking is optimized away. See above!
>>> spirit_bear(0xdeadbeef, 'People of the Cane')
(0xdeadbeef, 'People of the Cane', "Moksgm'ol", 'Ursus americanus kermodei')

해서. 무거운 짐을 시작 됩니다.

무너지잖아!? 왜 bear&quot ";? # 39, 면적 you& 네크베어드 맞죠?

곰 타입 검사 - 즉, 유형 검사를 bare-metal 입력 는 수동 외곽진입 형식 체크 인 Python 에 가깝게 복구할 수 있다. 곰, 호환성, 타사 종속물과의 입력을 위해 고안되었습니다 정판할 no 성능 저하를 (그 이상으로 의해 규정된 수작업식 외곽진입, 어쨌든). 기존 코드 및 테스트 suite 를 완벽하게 통합되어 수정 없이 감당할 수 있습니다.

39 에 익숙한 수작업식 외곽진입 everyone& 것이다. '너' 에서 직접 전달된 각 매개변수입니다 어설션 및 / 또는 반환 값 반환되었습니다 every 함수은 in your codebase. 무엇을 할 수 있는 상용 간단해진다는 이상의 평범한? 100 회 we& # 39 번, 구토, ve all seen it 의 구글플렉스 조금 입에 everytime 우리는 않았다. 이전 파르게 반복 된다. [그리고] (https://en.wikipedia.org/wiki/Don% 27t_repeat_yourself), ᅭ.

가방 있었다는 전달하십시오 준비되었음. # 39 에 대해 간략하게 let& solaris. 단순화됩니다 ' ()' 기능을 그대로 easy_spirit_bear 단 하나의 'str' 매개변수입니다. # 39 의 here& 어떤 수작업식 외곽진입 같습니다.

def easy_spirit_bear(kermode: str) -> str:
    assert isinstance(kermode, str), 'easy_spirit_bear() parameter kermode={} not of '.format(kermode)
    return_value = (kermode, "Moksgm'ol", 'Ursus americanus kermodei')
    assert isinstance(return_value, str), 'easy_spirit_bear() return value {} not of '.format(return_value)
    return return_value

파이썬 101, 그치? 우리들 대부분은 해당 클래스를 통과시켰다. 곰 타입 검사 입력하여 수동으로 위에서 정의된 함수를 수행하는 추출됩니다 외곽진입 붙여넣습니다 무중단으로 래퍼 같은 세밀한 검사를 수행할 수 있다는 이점도 있다 - 자동으로 함께 '보다는' 아서르티오너로 TypeError '애매한' 존재한다. # 39 의 here& 어떤 오토메이티드 외곽진입 같습니다.

def easy_spirit_bear_wrapper(*args, __beartype_func=easy_spirit_bear, **kwargs):
    if not (
        isinstance(args[0], __beartype_func.__annotations__['kermode'])
        if 0 < len(args) else
        isinstance(kwargs['kermode'], __beartype_func.__annotations__['kermode'])
        if 'kermode' in kwargs else True):
            raise TypeError(
                'easy_spirit_bear() parameter kermode={} not of {!r}'.format(
                args[0] if 0 < len(args) else kwargs['kermode'],
                __beartype_func.__annotations__['kermode']))

    return_value = __beartype_func(*args, **kwargs)

    if not isinstance(return_value, __beartype_func.__annotations__['return']):
        raise TypeError(
            'easy_spirit_bear() return value {} not of {!r}'.format(
                return_value, __beartype_func.__annotations__['return']))

    return return_value

39 의 it& 장황한. 하지만, s 도 sup&gt *&lt /sup&gt basically&lt it& # 39,, 빨리 수동 외곽진입. &lt sup&gt * Squinting suggested.&lt /sup>;;;

래퍼 (wrapper) 에 들어 있는 함수 또는 이터레이션에 완료하십시오 감사라고요 함수은 기록하십시오 부족 때문에 원래 취지대로 - 비록 비슷한 수의 테스트 (아마 거의 없습니다) 의 추가적인 비용을 절감할 수 있는 지 여부를 테스트하는, 어떻게 매개변수입니다 문자줄 점검됩니다 현재 함수 호출. # 39 can& 모든 전투, t 이길 수 있습니다. 임의의 함수 기능을 할 수 있는 래퍼 actually 유형 검사를 위해 생성된 안정적으로 등 이내에 275 흐름선 의 순수 파이썬? [스네이크 프리스킨] (https://en.wikipedia.org/wiki/Snake_Plissken), 사실 이야기들이거늘하나님 _&quot 말했다. 닥치는 대로 가져나왔어 _을 &quot. 그리고, 그렇습네다. 난 과민반을을 투명지에 네크베어드.

오빠예요-아니, 스슬리. 왜 bear&quot ";?

베어 비츠 오리. 즉시 던질 수 있지만, 연어 곰 http://support. 오리 덕 수 있습니다. &lt, 캐나다, 자연, 수, In sup&gt 깜짝 you.&lt /sup&gt. 다음 질문.

# 39 에 대한 베어스, So Hot What& 있겠습니까?

기존 솔루션 부문간 bare-metal 유형 검사를 수행할 not - 적어도 어느 I& # 39, ve 그레프트 추정했다. 그들은 모두 각 함수 호출 함수를 반복적으로 재검사하다 서명이 있는 점검됨 유형 . 일반적으로 단일 통화, 재검사 오버헤드에 ellipse1 무시할 때 모든 통화를 통해 집선됨 영향력이 없을지도 모른다고 제시하였다. Really, really 영향력이 없을지도 모른다고 제시하였다.

39 의 효율성을 it& 단순히 우려가 있다. 또한 기존 솔루션 고려하여 적지 않은 일반적인 면쪽 건이다. 여기에는 여기에 대답을 및 다른 대부분의 그렇지 않으면 모든 장난감 데코레이터 스택 오버플로 제공된다. 클래식 장애 다음과 같습니다.

  • 유형 검사를 못하고 키워드 인수 및 / 또는 반환 값 (예를 들어, [스위니로드] (https://stackoverflow.com/users/2387370/sweeneyrod) & # 39 의 ['@checkargs' 데코레이터] (https://stackoverflow.com/a/19684962/2809027)).
  • 지원할 수 있는 튜플에 (즉, 노조) ' ()' 이 유형의 수락됨 이신스턴스 내장.
  • 못해 이름을 전파하려면 닥슬링 및 기타 식별하면 메타데이터입니다 드래그합니다 래퍼 는 원래 기능을 지원한다.
  • 공급할 수 있는 최소 비유하사 유닛 테스트. (Kind critical. 있다)
  • '예외' 일반 '보다는' 특정 예외 오류가 있는 것이 아서르티오너로 TypeError 타입 검사. 정신, 유형 검사를 하는 인상을 위한 never 세분성 및 일반 존재한다. 여기서 비사양 베어스 베어 입력 성공할 수 없습니다. 모두 한 가지, 모든 곰!

    곰 런버트 입력

    곰 부족의 공간과 시간을 내어 비용 함수를 입력 명에게서 서명을 할 때 즉, 함수 정의 함수 호출 래퍼 함수가 반환되었습니다 @beartype 시간 뒤에 '에서' 데코레이터 꽂으십시오 데코레이터 할 수 있다. 데코레이터 이후 단 한 번씩 불렀으매 함수 정의, 이렇게 avamar 익올때 글리 모든. 곰 타입 검사 입력을 할 수 있으며, 고쳐주렴 백업이었습니다 케이크 및 먹어요. 이를 위해 '@beartype':

  1. 서명 및 주석, 원래 점검하고 있다.
  2. 구문 확인 원래 취지대로 무중단으로 시신이 래퍼 함수 유형. # 39, thaaat& 옳다. 파이썬 코드 생성 파이썬 코드를.
  3. 이 함수는 동적으로 래퍼 exec () '다' 를 통해 기본 제공.
  4. 되돌려줍니다 래퍼 (wrapper) 이 있다. 그럴까요? # 39 의 let& 깊이형 둘러보기 끝.
# If the active Python interpreter is *NOT* optimized (e.g., option "-O" was
# *NOT* passed to this interpreter), enable type checking.
if __debug__:
    import inspect
    from functools import wraps
    from inspect import Parameter, Signature

    def beartype(func: callable) -> callable:
        '''
        Decorate the passed **callable** (e.g., function, method) to validate
        both all annotated parameters passed to this callable _and_ the
        annotated value returned by this callable if any.

        This decorator performs rudimentary type checking based on Python 3.x
        function annotations, as officially documented by PEP 484 ("Type
        Hints"). While PEP 484 supports arbitrarily complex type composition,
        this decorator requires _all_ parameter and return value annotations to
        be either:

        * Classes (e.g., `int`, `OrderedDict`).
        * Tuples of classes (e.g., `(int, OrderedDict)`).

        If optimizations are enabled by the active Python interpreter (e.g., due
        to option `-O` passed to this interpreter), this decorator is a noop.

        Raises
        ----------
        NameError
            If any parameter has the reserved name `__beartype_func`.
        TypeError
            If either:
            * Any parameter or return value annotation is neither:
              * A type.
              * A tuple of types.
            * The kind of any parameter is unrecognized. This should _never_
              happen, assuming no significant changes to Python semantics.
        '''

        # Raw string of Python statements comprising the body of this wrapper,
        # including (in order):
        #
        # * A "@wraps" decorator propagating the name, docstring, and other
        #   identifying metadata of the original function to this wrapper.
        # * A private "__beartype_func" parameter initialized to this function.
        #   In theory, the "func" parameter passed to this decorator should be
        #   accessible as a closure-style local in this wrapper. For unknown
        #   reasons (presumably, a subtle bug in the exec() builtin), this is
        #   not the case. Instead, a closure-style local must be simulated by
        #   passing the "func" parameter to this function at function
        #   definition time as the default value of an arbitrary parameter. To
        #   ensure this default is *NOT* overwritten by a function accepting a
        #   parameter of the same name, this edge case is tested for below.
        # * Assert statements type checking parameters passed to this callable.
        # * A call to this callable.
        # * An assert statement type checking the value returned by this
        #   callable.
        #
        # While there exist numerous alternatives (e.g., appending to a list or
        # bytearray before joining the elements of that iterable into a string),
        # these alternatives are either slower (as in the case of a list, due to
        # the high up-front cost of list construction) or substantially more
        # cumbersome (as in the case of a bytearray). Since string concatenation
        # is heavily optimized by the official CPython interpreter, the simplest
        # approach is (curiously) the most ideal.
        func_body = '''
@wraps(__beartype_func)
def func_beartyped(*args, __beartype_func=__beartype_func, **kwargs):
'''

        # "inspect.Signature" instance encapsulating this callable's signature.
        func_sig = inspect.signature(func)

        # Human-readable name of this function for use in exceptions.
        func_name = func.__name__ + '()'

        # For the name of each parameter passed to this callable and the
        # "inspect.Parameter" instance encapsulating this parameter (in the
        # passed order)...
        for func_arg_index, func_arg in enumerate(func_sig.parameters.values()):
            # If this callable redefines a parameter initialized to a default
            # value by this wrapper, raise an exception. Permitting this
            # unlikely edge case would permit unsuspecting users to
            # "accidentally" override these defaults.
            if func_arg.name == '__beartype_func':
                raise NameError(
                    'Parameter {} reserved for use by @beartype.'.format(
                        func_arg.name))

            # If this parameter is both annotated and non-ignorable for purposes
            # of type checking, type check this parameter.
            if (func_arg.annotation is not Parameter.empty and
                func_arg.kind not in _PARAMETER_KIND_IGNORED):
                # Validate this annotation.
                _check_type_annotation(
                    annotation=func_arg.annotation,
                    label='{} parameter {} type'.format(
                        func_name, func_arg.name))

                # String evaluating to this parameter's annotated type.
                func_arg_type_expr = (
                    '__beartype_func.__annotations__[{!r}]'.format(
                        func_arg.name))

                # String evaluating to this parameter's current value when
                # passed as a keyword.
                func_arg_value_key_expr = 'kwargs[{!r}]'.format(func_arg.name)

                # If this parameter is keyword-only, type check this parameter
                # only by lookup in the variadic "**kwargs" dictionary.
                if func_arg.kind is Parameter.KEYWORD_ONLY:
                    func_body += '''
    if {arg_name!r} in kwargs and not isinstance(
        {arg_value_key_expr}, {arg_type_expr}):
        raise TypeError(
            '{func_name} keyword-only parameter '
            '{arg_name}={{}} not a {{!r}}'.format(
                {arg_value_key_expr}, {arg_type_expr}))
'''.format(
                        func_name=func_name,
                        arg_name=func_arg.name,
                        arg_type_expr=func_arg_type_expr,
                        arg_value_key_expr=func_arg_value_key_expr,
                    )
                # Else, this parameter may be passed either positionally or as
                # a keyword. Type check this parameter both by lookup in the
                # variadic "**kwargs" dictionary *AND* by index into the
                # variadic "*args" tuple.
                else:
                    # String evaluating to this parameter's current value when
                    # passed positionally.
                    func_arg_value_pos_expr = 'args[{!r}]'.format(
                        func_arg_index)

                    func_body += '''
    if not (
        isinstance({arg_value_pos_expr}, {arg_type_expr})
        if {arg_index} < len(args) else
        isinstance({arg_value_key_expr}, {arg_type_expr})
        if {arg_name!r} in kwargs else True):
            raise TypeError(
                '{func_name} parameter {arg_name}={{}} not of {{!r}}'.format(
                {arg_value_pos_expr} if {arg_index} < len(args) else {arg_value_key_expr},
                {arg_type_expr}))
'''.format(
                    func_name=func_name,
                    arg_name=func_arg.name,
                    arg_index=func_arg_index,
                    arg_type_expr=func_arg_type_expr,
                    arg_value_key_expr=func_arg_value_key_expr,
                    arg_value_pos_expr=func_arg_value_pos_expr,
                )

        # If this callable's return value is both annotated and non-ignorable
        # for purposes of type checking, type check this value.
        if func_sig.return_annotation not in _RETURN_ANNOTATION_IGNORED:
            # Validate this annotation.
            _check_type_annotation(
                annotation=func_sig.return_annotation,
                label='{} return type'.format(func_name))

            # Strings evaluating to this parameter's annotated type and
            # currently passed value, as above.
            func_return_type_expr = (
                "__beartype_func.__annotations__['return']")

            # Call this callable, type check the returned value, and return this
            # value from this wrapper.
            func_body += '''
    return_value = __beartype_func(*args, **kwargs)
    if not isinstance(return_value, {return_type}):
        raise TypeError(
            '{func_name} return value {{}} not of {{!r}}'.format(
                return_value, {return_type}))
    return return_value
'''.format(func_name=func_name, return_type=func_return_type_expr)
        # Else, call this callable and return this value from this wrapper.
        else:
            func_body += '''
    return __beartype_func(*args, **kwargs)
'''

        # Dictionary mapping from local attribute name to value. For efficiency,
        # only those local attributes explicitly required in the body of this
        # wrapper are copied from the current namespace. (See below.)
        local_attrs = {'__beartype_func': func}

        # Dynamically define this wrapper as a closure of this decorator. For
        # obscure and presumably uninteresting reasons, Python fails to locally
        # declare this closure when the locals() dictionary is passed; to
        # capture this closure, a local dictionary must be passed instead.
        exec(func_body, globals(), local_attrs)

        # Return this wrapper.
        return local_attrs['func_beartyped']

    _PARAMETER_KIND_IGNORED = {
        Parameter.POSITIONAL_ONLY, Parameter.VAR_POSITIONAL, Parameter.VAR_KEYWORD,
    }
    '''
    Set of all `inspect.Parameter.kind` constants to be ignored during
    annotation- based type checking in the `@beartype` decorator.

    This includes:

    * Constants specific to variadic parameters (e.g., `*args`, `**kwargs`).
      Variadic parameters cannot be annotated and hence cannot be type checked.
    * Constants specific to positional-only parameters, which apply to non-pure-
      Python callables (e.g., defined by C extensions). The `@beartype`
      decorator applies _only_ to pure-Python callables, which provide no
      syntactic means of specifying positional-only parameters.
    '''

    _RETURN_ANNOTATION_IGNORED = {Signature.empty, None}
    '''
    Set of all annotations for return values to be ignored during annotation-
    based type checking in the `@beartype` decorator.

    This includes:

    * `Signature.empty`, signifying a callable whose return value is _not_
      annotated.
    * `None`, signifying a callable returning no value. By convention, callables
      returning no value are typically annotated to return `None`. Technically,
      callables whose return values are annotated as `None` _could_ be
      explicitly checked to return `None` rather than a none-`None` value. Since
      return values are safely ignorable by callers, however, there appears to
      be little real-world utility in enforcing this constraint.
    '''

    def _check_type_annotation(annotation: object, label: str) -> None:
        '''
        Validate the passed annotation to be a valid type supported by the
        `@beartype` decorator.

        Parameters
        ----------
        annotation : object
            Annotation to be validated.
        label : str
            Human-readable label describing this annotation, interpolated into
            exceptions raised by this function.

        Raises
        ----------
        TypeError
            If this annotation is neither a new-style class nor a tuple of
            new-style classes.
        '''

        # If this annotation is a tuple, raise an exception if any member of
        # this tuple is not a new-style class. Note that the "__name__"
        # attribute tested below is not defined by old-style classes and hence
        # serves as a helpful means of identifying new-style classes.
        if isinstance(annotation, tuple):
            for member in annotation:
                if not (
                    isinstance(member, type) and hasattr(member, '__name__')):
                    raise TypeError(
                        '{} tuple member {} not a new-style class'.format(
                            label, member))
        # Else if this annotation is not a new-style class, raise an exception.
        elif not (
            isinstance(annotation, type) and hasattr(annotation, '__name__')):
            raise TypeError(
                '{} {} neither a new-style class nor '
                'tuple of such classes'.format(label, annotation))

# Else, the active Python interpreter is optimized. In this case, disable type
# checking by reducing this decorator to the identity decorator.
else:
    def beartype(func: callable) -> callable:
        return func

및 [레이스크] (https://stackoverflow.com/users/2809027/cecil-curry) ',' 더 빠르게 깔의 유형 검사를 @beartype 것 "이라고 말했다. 그리고 그건 합니다.

경고, Curses 및 빈 약속

아무것도아니야 완벽하겠어요. Typing._ _even 베어

경고 I: 견제받지 않는 기본값과

베어 입력 높여줍니까 not 유형 검사 우 패스트 매개변수입니다 할당되었다는 기본값입니다. 이론적으로 보인다. 스택 오버플로 오토메이티드 한 적은 있지만 275 흐름선 또는 분명 아니다. 세이프 (.probably 완전히 unsafe) 때 그들은 그들이 행한 하였노라너희가 알고 있다는 추정이 함수은 구현자 정의 기본값입니다. 이후 일반적으로 상수입니다 기본값과 (.they& 게 좋을! # 39; d), 다시 검사 유형은 상수입니다 변경되지 않는 것 중 하나 이상의 기본값과 기본적인 주의 각 함수 호출 지정받습니다 위반하다 베어 입력: # 39, t, Don& &quot 교도관님도요 반복하십시오 비해 ooooveroooo-oooover again.&quot. Show me 잘못을 업보테스 내아기마저도 샤워 사용할 수 있습니다.

경고 II: Pep 484 없습니다.

[PEP 484] (https://www.python.org/dev/peps/pep-0484) (; ; 문자 Hints&quot &quot) 함수를 사용하여 주석입니다 공식적인 첫 선보인 [PEP 3107] (https://www.python.org/dev/peps/pep-3107/) (&quot 함수은 Annotations" ;). 표면적으로 이 형식화 는 파이썬 3.5 에 새로운 최상위 ['를' 모듈에서는] (https://docs.python.org/3/library/typing.html), 표준 API 를 작성하기 위해 복잡한 유형 중 임의로 간단해진다는 유형 (예를 들어, '호출 [[Arg1Type, Arg2Type], 레오네티페]', 타입 설명하는 함수은 받아들이는 두 가지 주장 유형 '가치' 와 '와' Arg2Type Arg1Type 반환 유형 '레오네티페'). 곰 저들이요 어떤 입력을 지원합니다. 이론적으로 보인다. 스택 오버플로 오토메이티드 한 적은 있지만 275 흐름선 또는 분명 아니다. 그러나 노조는 이 같은 방식으로 추상형데이터타입 입력 크기:, 곰, 지원 '이신스턴스 내장 ()' 는 인상을 유형: 으로 tuples. 표면적으로 대응됩니다 티핑.유니슨 '이' 경고 '를 동시에 지원할 수 있는' 티핑.유니슨 명백하네 유형 - 튜플을 수락됨 @beartype only 임의로 복잡한 유형 '' 지원부에서는 간단한 클래스뿐만. 내 국방, 275 흐름선.

It # 39 테스트 또는 Didn& 일이 없다.

39 의 here&, [사진을] (https://gist.github.com/leycec/3d48cc60e7d5fe8860b077acb067dc54) 것이다. &lt sup&gt 이해했소, gist?;; # 39, ll 정지점을 i& now.&lt /sup>;

데코레이터 @beartype '와' 자체가 이러한 ['피오트레스트'] (https://github.com/pytest-dev/pytest) 테스트 테스트 제품군을 기존 수정 없이 완벽하게 통합되어 수 있습니다. # 39, 소중한, isn& t it? 이제 아니예 주문하신거 필수 네크베어드 시인했다.

역사 apiu 폭력

파이썬 3.5 제공하지 실제 사용 지원 PEP 484 유형. wat?

39 의 it& 진실: 아니, 아니 유형: nuthin& # 39, 추론 유형 검사를 유형이 없습니다. 대신 대형 업체들이 자사의 전체 실행하십시오 것으로 보인다고 래퍼 (wrapper) 구축 등 타사 스피통 코드 일상적으로 통해 팩스 지원 (예: [미피] (https://github.com/JukkaL/mypy)). 물론 이러한 래퍼 정판할:

  • A penalty. 호환성에서는 같은 [공식 미피 FAQ] (https://mypy.readthedocs.io/en/latest/faq.html # 내 기존 파이썬 코드를 입력하여 확인 미피 사용할 수 있습니까?) 이에 대해 자주 묻는 질문 유형 (type) 으로 미피 &quot 말합니다, 파이썬 코드를 사용할 수 있습니까?? 내 기존 확인란 ": It depends. 호환성에서는 &quot, 파이썬 피쳐에는 있지만, 일부 또는 전부가 아직 구현되지 않은 것은 매우 좋은 supported.&quot. [후속 FAQ 응답] 는 (https://mypy.readthedocs.io/en/latest/faq.html # 다른 프로그램을 어떻게 적용됩니까 미피 표준 파이썬) 이 비호환성이 적시한 같이 써서 다음과 같이 밝혔다:
  • &quot 지유르 속성뿐 명시성 및 사용, 명시성 포로토콜 representation.&quot 코드 합니다. 경찰, sup&gt &lt Grammar &quot 내용을 볼 수 있는 explicit";; 들어 올리고 암시적입니다 frown.&lt /sup>;
  • &quot, 미피 모듈형의 효율형 유형 검사 및 지원 할 것 같은 이 배제하기 위해 몇 가지 언어 런타임 타입 검사 기능 추가 임의의 수 있습니다. 그러나 이런 다양한 기능을 지원하게 될 가능성이 있는 제한된 형태 (예를 들어, 런타임 수정을 대해서만 지원됩니다 클래스 또는 메서드을 레지스터링 따라 동적 또는 "패치 가능한") .&quot.
  • 전체 목록은 통사 비호환성 http://schmidt. devlib. [_&quot, 일반적인 issues&quot 다루는, _입니다] (https://mypy.readthedocs.io/en/latest/common_issues.html # 일반적인 문제). # 39 의 it& not 예쁘다. 이제 방금 그들이성년에 유형 검사를 통해 전체 코드 s 에서 구축하십시오, 이틀 뒤 세이스트 everyone& # 39 의 비즈니스 캐주얼 차림으로 핑크 슬립 후보 릴리스에는 및 알맞은 HR 실수할 수 있는 휴대용 통해 대대적인 칸막이 cum 만카베. 감사합니다 많이, 미피.
  • A , 해석 코드를 정적으로 입력되었는지 불구하고 성능 저하. 사십 년 것임을 시사하고 해석 코드를 정적으로 입력되었는지 삶은 컴퓨터 과학 (다른 .all 기술입니까 equal) 보다 빠른 속도가 느린 해석 코드가 아닌 동적으로 입력되었는지 합니다. 의 파이썬, up 은 새로운 아래에있어.
  • 추가 아닌 사소한 종속물, 원거리일수록:
  • 이 입히지 버그 함유, 특히 플랫폼 구축 프로젝트.
  • 유지보수 부담을 프로젝트 개발.
  • 공격 가능성을 서피스입니다. 그로 인하여 내가 귀도: &quot, 왜? 왜 추상 apiu 발명, t # 39 위로 weren& 경우 이미 자신의 의지가 있는 &quot 추상화, 실제로 일을 구체적인 apiu 있지요? 왜 꼭 자유 오픈 소스 시장에 대한 운명을 남겨두십시오 만 피토니스타스 관절염? 왜 또 다른 테크노 문제 만들 수 있는 것은 그동안 사소 에 있는 275 선 데코레이터 공식 파이썬 스테드리브? 저는 전혀 Python and I scream 합니다.
해설 (8)
해결책

관용구 () 는 어떤 함수를 파이썬 document 가장 확실하게 얻을 수 있을 것으로 기대하고 있다 그리고 불과 있는모든 사용하려고 할 지 잘 전달 함수 및 인컨텍스트 데이터베이스에구성원을 스피커에만 예외 오류 및 올리는 대신 typeerror '속성'. 타입 검사 최대한 피해야 한다는 것과 덕 타이핑 위배된다. 상황에 따라 테스트 값을 확인 할 수 있다.

정말 이해가 됩니다 는 유일한 곳 검증 시스템 또는 서브시스템과 진입점이 같은 웹 양식, 명령행을 인수 등). 다른 모든 기능을 제대로 문서화했습니다 # 39, s, it& deltamove 너회의 caller& # 39, 적절한 인수만 전달하십시오 책임입니다.

해설 (10)

편집: 2019년 기준으로 좁히어 가 더 많은 지원을 위한 파이썬, 주석 및 정적임 체크인 문자 사용 1 모듈에서는 체크아웃합니다 [입력] 및 미피. 2013년 는 오토메이티드 다음과 같습니다.

일반적으로 파이썬 유형 검사를 없습니다. 파이썬, 사용할 수 있는 것이 더 일반적인 [덕 타이핑] (http://en.wikipedia.org/wiki/Duck_typing). 예:

에서는 코드, solaris. 작업자쪽에서 인수 (in your 들어 'a') 등과 같은 '돌팔이' 와 'int' 등과 같은 int 볼넷. 예를 들면 다음과 같습니다.

def my_function(a):
    return a + 7

즉, 정수 뿐만 아니라 모든 사용자 정의 함수 작동합니까 있습니까 수행됨 add 정의된 메서드를 사용하여 클래스의 유동합니다 '때문에' (때로는 아무것도아니야) 가 해야 할 일이 적은 경우, 또는 다른 사람이 하는 함수를 확장하십시오 작동합니까 something else. 그러나 경우에 따라 이 같은 일이 할 수 있는 'int', 그럼 할 수 있습니다.

def my_function(a):
    b = int(a) + 7
    c = (5, 6, 3, 123541)[b]
    return c

아직도 그 기능을 사용할 수 있는 '모든' a '는' int 메서드입니다.

네 다른 질문, 내가 생각하는 것이 될 수 있는 (이 때는 다른 어떤 대답을 할 수 있다 "고 말했다.

def my_function(a, b, c):
    assert 0 < b < 10
    assert c        # A non-empty string has the Boolean value True

또는

def my_function(a, b, c):
    if 0 < b < 10:
        # Do stuff with b
    else:
        raise ValueError
    if c:
        # Do stuff with c
    else:
        raise ValueError

데코레이터 내가 몇 가지 유형 검사를 했다.

import inspect

def checkargs(function):
    def _f(*arguments):
        for index, argument in enumerate(inspect.getfullargspec(function)[0]):
            if not isinstance(arguments[index], function.__annotations__[argument]):
                raise TypeError("{} is not of type {}".format(arguments[index], function.__annotations__[argument]))
        return function(*arguments)
    _f.__doc__ = function.__doc__
    return _f

def coerceargs(function):
    def _f(*arguments):
        new_arguments = []
        for index, argument in enumerate(inspect.getfullargspec(function)[0]):
            new_arguments.append(function.__annotations__[argument](arguments[index]))
        return function(*new_arguments)
    _f.__doc__ = function.__doc__
    return _f

if __name__ == "__main__":
    @checkargs
    def f(x: int, y: int):
        """
        A doc string!
        """
        return x, y

    @coerceargs
    def g(a: int, b: int):
        """
        Another doc string!
        """
        return a + b

    print(f(1, 2))
    try:
        print(f(3, 4.0))
    except TypeError as e:
        print(e)

    print(g(1, 2))
    print(g(3, 4.0))
해설 (1)

'를 사용하는 것이 한 가지 방법은 어설션':

def myFunction(a,b,c):
    "This is an example function I'd like to check arguments of"
    assert isinstance(a, int), 'a should be an int'
    # or if you want to allow whole number floats: assert int(a) == a
    assert b > 0 and b < 10, 'b should be betwen 0 and 10'
    assert isinstance(c, str) and c, 'c should be a non-empty string'
해설 (5)

데코레이터 되돌려줍니다 문자줄 집행 동의하십시오 에서 사용할 수 있습니다 / 피토네코라토리브라리

39, it& 아주 쉽고 판독값:

@accepts(int, int, float)
def myfunc(i1, i2, i3):
    pass
해설 (2)

여러 가지입니다 가변입니다 있는 것을 확인할 수 있다. 따라서 목록에 대한 몇 가지:

  • '목표' 와 '는 이신스턴스 (obj mm_mail_doc.)' 기능을 사용하면 해당 변수 'True' 는 것은 '유형' 너 같은 유형의 나열되었습니다.

  • '아서브클레스 (목표, class)' 기능을 사용하면 변수에 필요한 경우 '목표' 은 '목표' 및 '진정한' 의 하위 클래스 '클래스'. 예를 들어 'a' 진정한 '가치' 다시그것들을 제공하십시오 아서브클레스 (토끼, 동물)

'-', '이 함수에 의해 또 다른 예를 보이고 헤이스타르 super_len':

def super_len(o):
    if hasattr(o, '__len__'):
        return len(o)

    if hasattr(o, 'len'):
        return o.len

    if hasattr(o, 'fileno'):
        try:
            fileno = o.fileno()
        except io.UnsupportedOperation:
            pass
        else:
            return os.fstat(fileno).st_size

    if hasattr(o, 'getvalue'):
        # e.g. BytesIO, cStringIO.StringI
        return len(o.getvalue())
  • '보통' 보다 수준 높은 헤이스타르 굽힐때 덕 타이핑 및 생각하신거야 pythonic 하지만 그 기간이 더 것가운데 자기의견.

참고로, '그냥' 테스트, 그렇지 않으면 사용할 경우 일반적으로 사용되는 어설션 제표를 / else '그냥' 명령문입니다.

해설 (0)

I did 아주 조금 해당 주제에 대한 수사 최근 때부터 많은 [라이브러리보다는] (https://smarie.github.io/python-valid8/other_libs/) I found 거기에 만족하지 않았다.

이러한 문제를 해결하기 위해, 이 이름은 개발 됐지 내가 라리브러리 [valid8] (https://smarie.github.io/python-valid8/). 문서에 설명된 것처럼, 이는 주로 값에 대한 검증 (비록 번들로 제공 단순 자료형의 검증 기능이 너무) 는 같은 종류, 진실이며당신이 강조표시할 지정값이 연관시킵니다 pep484 기반 검사기에서 [적용] (https://github.com/RussBaz/enforce) 또는 [피티페스] (https://github.com/Stewori/pytypes).

그것은 여분이라일러라 검증 기능을 수행하는 것과 valid8 '혼자' (및 ['mini_lambda'] (https://smarie.github.io/python-mini-lambda/), 그러나 그것은 실제로 정의하십시오 검증 논리를 - 선택적입니다) 의 케이스.

# for type validation
from numbers import Integral
from valid8 import instance_of

# for value validation
from valid8 import validate_arg
from mini_lambda import x, s, Len

@validate_arg('a', instance_of(Integral))
@validate_arg('b', (0 < x) & (x < 10))
@validate_arg('c', instance_of(str), Len(s) > 0)
def my_function(a: Integral, b, c: str):
    """an example function I'd like to check the arguments of."""
    # check that a is an int
    # check that 0 < b < 10
    # check that c is not an empty string

# check that it works
my_function(0.2, 1, 'r')  # InputValidationError for 'a' HasWrongType: Value should be an instance of . Wrong value: [0.2].
my_function(0, 0, 'r')    # InputValidationError for 'b' [(x > 0) & (x < 10)] returned [False]
my_function(0, 1, 0)      # InputValidationError for 'c' Successes: [] / Failures: {"instance_of_": "HasWrongType: Value should be an instance of . Wrong value: [0]", 'len(s) > 0': "TypeError: object of type 'int' has no len()"}.
my_function(0, 1, '')     # InputValidationError for 'c' Successes: ["instance_of_"] / Failures: {'len(s) > 0': 'False'}

그리고 이것은 유형 검사를 시행할 수 있는 '위임' 와 같은 예제에서와 leveraging PEP484 유형: 힌트:

# for type validation
from numbers import Integral
from enforce import runtime_validation, config
config(dict(mode='covariant'))  # type validation will accept subclasses too

# for value validation
from valid8 import validate_arg
from mini_lambda import x, s, Len

@runtime_validation
@validate_arg('b', (0 < x) & (x < 10))
@validate_arg('c', Len(s) > 0)
def my_function(a: Integral, b, c: str):
    """an example function I'd like to check the arguments of."""
    # check that a is an int
    # check that 0 < b < 10
    # check that c is not an empty string

# check that it works
my_function(0.2, 1, 'r')  # RuntimeTypeError 'a' was not of type 
my_function(0, 0, 'r')    # InputValidationError for 'b' [(x > 0) & (x < 10)] returned [False]
my_function(0, 1, 0)      # RuntimeTypeError 'c' was not of type 
my_function(0, 1, '')     # InputValidationError for 'c' [len(s) > 0] returned [False].
해설 (0)

이 같은 일이 정상적으로 할 수 있습니다.

def myFunction(a,b,c):
   if not isinstance(a, int):
      raise TypeError("Expected int, got %s" % (type(a),))
   if b = 10:
      raise ValueError("Value %d out of range" % (b,))
   if not c:
      raise ValueError("String was empty")

   # Rest of function
해설 (4)

이 유형의 입력을 인수만 함수 호출 시 확인합니다.

def func(inp1:int=0,inp2:str="*"):

    for item in func.__annotations__.keys():
        assert isinstance(locals()[item],func.__annotations__[item])

    return (something)

first=7
second="$"
print(func(first,second))

또한 두 번째 확인란 함께 '= 9' (어설션 오류 열거하십시오 합니다)

해설 (1)
def someFunc(a, b, c):
    params = locals()
    for _item in params:
        print type(params[_item]), _item, params[_item]

데모:

>> someFunc(1, 'asd', 1.0)
>>  a 1
>>  c 1.0
>>  b asd

자세한 내용 [지역 ()] [1]

[1]: http://docs.python.org/2/library/functions.html # 지역

해설 (0)

스케쳐내 인증 기능을 수행할 수 있는 논리를 데코레이터 다음과 같은 여러 기능을 추가할 수 있습니다

def deco(func):
     def wrapper(a,b,c):
         if not isinstance(a, int)\
            or not isinstance(b, int)\
            or not isinstance(c, str):
             raise TypeError
         if not 0 < b < 10:
             raise ValueError
         if c == '':
             raise ValueError
         return func(a,b,c)
     return wrapper

사용하고 있다.

@deco
def foo(a,b,c):
    print 'ok!'

이를 통해 희망을!

해설 (7)

확인하고 싶다면 '', '' 뿐만 아니라 일반 인수만 콰리스 args 검색하기를 한 지역 () '기능을 사용할 수 있습니다' 로 자신의 첫 번째 문에 함수 정의 to get a dictionary of arguments.

그러면 '유형 ()', 예를 들어 이에 대해 검토해 인수만 딕트 반복.

def myfunc(my, args, to, this, function, **kwargs):
    d = locals()
    assert(type(d.get('x')) == str)
    for x in d:
        if x != 'x':
            assert(type(d[x]) == x
    for x in ['a','b','c']:
        assert(x in d)

    whatever more...
해설 (0)

해결책이 아니다 싶으면 알 수 있으나, 일부 특정 매개변수입니다 제한 함수 호출이 프로이터 파이썬 함수를 사용하여 프로토타입 문법검사기} {추상형데이터타입 선택해야 합니다. 다음 링크를 참조할 수 있습니다. https://github.com/mohit-thakur-721/proator

해설 (0)
def myFunction(a,b,c):
"This is an example function I'd like to check arguments of"
    if type( a ) == int:
       #dostuff
    if 0 < b < 10:
       #dostuff
    if type( C ) == str and c != "":
       #dostuff
해설 (0)