Do union types actually exist in python?

时光怂恿深爱的人放手 提交于 2019-11-28 11:13:31

Union typing is only needed when you have a statically typed language, as you need to declare that an object can return one of multiple types (in your case an int or str, or in the other example str or NoneType).

Python deals in objects only, so there is never a need to even consider 'union types'. Python functions return what they return, if the programmer wants to return different types for different results then that's their choice. The choice is then an architecture choice, and makes no difference to the Python interpreter (so there is nothing to 'benchmark' here).

Python 3.5 does introduce a standard for creating optional type hints, and that standard includes Union[...] and Optional[...] annotations.

the type itself does not exist because Python is just a dynamically typed language, however, in newer Python versions, Union Type is an option for Type Hinting,

from typing import Union,TypeVar

T = TypeVar('T')
def f(x: T) -> Union[str, None]:
    if x:
        return "x"

you can use that to annotate your code, thus enabling IDE/Editor level syntax checking.

Adding to @MartijnPieters answer:

But is the way python was actually intended to be used?

Returning different type depending on the param is never a good practice in any language. This makes testing, maintaining and extending the code really difficult and IMHO is an anti-pattern (but of course sometimes necessary evil). The results should at least be related via having common interface.

The only reason union was introduced to C was due to performance gain. But in Python you don't have this performance gain due to dynamic nature of the language (as Martijn noticed). Actually introducing union would lower performance since the size of union is always the size of the biggest member. Thus Python will never have C-like union.

Here are a couple of options to deal with use-cases where you need a tagged union/sum type in Python:

  • Enum + Tuples

    from enum import Enum
    Token = Enum('Token', ['Number', 'Operator', 'Identifier', 'Space', 'Expression'])
    
    (Token.Number, 42)                            # int type
    (Token.Operator, '+')                         # str type 1
    (Token.Identifier, 'foo')                     # str type 2
    (Token.Space, )                               # no data
    (Token.Expression, 'lambda', 'x', 'x+x')      # multiple data
    
  • isinstance

    if isinstance(token, int):
        # Number type
    if isinstance(token, str):
        # Identifier type
    
  • sumtypes module

These approaches all have their various drawbacks, of course.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!