1. 程式人生 > 實用技巧 >Python靜態型別

Python靜態型別

Mypy是Python的可選靜態型別檢查器。您可以在Python程式中新增型別提示(PEP 484),並使用mypy進行靜態型別檢查。查詢程式中的錯誤,甚至不執行它們!

安裝Mypy

Mypy需要執行Python 3.5或更高版本。下面程式碼是用的Python 3.7 使用pip安裝mypy:

$ python3 -m pip install mypy

看幾個簡單例子:
平時我們程式碼大概都是下面的樣子:

# 引數name的型別是未知的
# 返回的型別也是未知的
def greeting(name):
    return 'Hello ' + name

稍微修改一些

# 引數name後面跟了:str 代表name期望是str型別
# 引數括號後面跟了->str代表返回型別為str型別 def greeting(name: str) -> str: return 'Hello ' + name x: str = 'xxx' # 宣告一個變數為str型別 greeting(x) # Hello xxx greeting(123) # TypeError: can only concatenate str (not "int") to str

到目前為止僅有str、float等基本型別,使用list、tuple複雜型別需要引用typing中的類

LIST

陣列型別

from typing import
List # 引數names為list型別並且元素都是str型別 # 返回為None def greet_all(names: List[str]) -> None: for name in names: print('Hello ' + name) names = ["Alice", "Bob", "Charlie"] ages = [10, 20, 30] greet_all(names) # Ok! greet_all(ages) #出錯了 Error due to incompatible types

Dict

字典型別

from typing import
Dict # Dict[int, str] int代表key型別, str代表val型別 def test(t: Dict[int, str]) -> Dict: return t test({1: '234'}) # {1: '234'}

Iterable

可以迭代型別包括 List、Set、Tuple、Str、Dict

def greeting(names: Iterable[str]) -> None:
    for name in names:
        print(name)

greeting(['aaa', 'bbb']) # list aaa bbb
greeting(('ccc', 'ddd')) # tuple ccc ddd
greeting({'eee', 'fff'}) # set eee fff
greeting({'ggg': 'hhh'}) # dict ggg
greeting('123') # str 1 2 3 
greeting(678) # error: Argument 1 to "greeting" has incompatible type "int"; expected "Iterable[str]"

Union

接受多個指定型別,但不接受除此外的型別

from typing import Union
# user_id 只能為int或者str
def normalize_id(user_id: Union[int, str]) -> str:
    if isinstance(user_id, int):
        return 'user-{}'.format(100000 + user_id)
    else:
        return user_id
normalize_id(1) # user-100001
normalize_id('2') # 2

Optional

可選型別,給引數設定預設值

from typing import Optional

# Optional[str]只是Union [str,None]的簡寫或別名。它主要是為了方便幫助功能簽名看起來更清潔
# Optional[str, int] 只能包含一個型別, 這樣是不正確的
def greeting(name: Optional[str] = None) -> str:
    if name is None:
        name = 'stranger'
    return 'Hello, ' + name
greeting() # Hello, stranger
greeting('123') # Hello, 123

Any

有時候我們不確定是什麼型別的時候可以用到Any

from typing import Any

def greeting(name: Any = None) -> str:
    if name is None:
        name = 'stranger'

    return 'Hello, ' + str(name)

greeting() # Hello, stranger
greeting('123') # Hello, 123
greeting(234) # Hello, 234
greeting([345]) # Hello, [345]

TypeVar

自定義型別

from typing import TypeVar

T = TypeVar('T') # 任意型別
A = TypeVar('A', int, str) # A型別只能為int或str
def test(t: A) -> None:
    print(t)
test(1)

參考連結:

https://www.jianshu.com/p/37f945cd91c3

官方連結:

https://docs.python.org/3.6/library/typing.html#distinct