What's the canonical way to check for type in Python?

后端 未结 13 1080
南旧
南旧 2020-11-21 07:34

What is the best way to check whether a given object is of a given type? How about checking whether the object inherits from a given type?

Let\'s say I have an objec

13条回答
  •  我寻月下人不归
    2020-11-21 08:03

    After the question was asked and answered, type hints were added to Python. Type hints in Python allow types to be checked but in a very different way from statically typed languages. Type hints in Python associate the expected types of arguments with functions as runtime accessible data associated with functions and this allows for types to be checked. Example of type hint syntax:

    def foo(i: int):
        return i
    
    foo(5)
    foo('oops')
    

    In this case we want an error to be triggered for foo('oops') since the annotated type of the argument is int. The added type hint does not cause an error to occur when the script is run normally. However, it adds attributes to the function describing the expected types that other programs can query and use to check for type errors.

    One of these other programs that can be used to find the type error is mypy:

    mypy script.py
    script.py:12: error: Argument 1 to "foo" has incompatible type "str"; expected "int"
    

    (You might need to install mypy from your package manager. I don't think it comes with CPython but seems to have some level of "officialness".)

    Type checking this way is different from type checking in statically typed compiled languages. Because types are dynamic in Python, type checking must be done at runtime, which imposes a cost -- even on correct programs -- if we insist that it happen at every chance. Explicit type checks may also be more restrictive than needed and cause unnecessary errors (e.g. does the argument really need to be of exactly list type or is anything iterable sufficient?).

    The upside of explicit type checking is that it can catch errors earlier and give clearer error messages than duck typing. The exact requirements of a duck type can only be expressed with external documentation (hopefully it's thorough and accurate) and errors from incompatible types can occur far from where they originate.

    Python's type hints are meant to offer a compromise where types can be specified and checked but there is no additional cost during usual code execution.

    The typing package offers type variables that can be used in type hints to express needed behaviors without requiring particular types. For example, it includes variables such as Iterable and Callable for hints to specify the need for any type with those behaviors.

    While type hints are the most Pythonic way to check types, it's often even more Pythonic to not check types at all and rely on duck typing. Type hints are relatively new and the jury is still out on when they're the most Pythonic solution. A relatively uncontroversial but very general comparison: Type hints provide a form of documentation that can be enforced, allow code to generate earlier and easier to understand errors, can catch errors that duck typing can't, and can be checked statically (in an unusual sense but it's still outside of runtime). On the other hand, duck typing has been the Pythonic way for a long time, doesn't impose the cognitive overhead of static typing, is less verbose, and will accept all viable types and then some.

提交回复
热议问题