Python函式註解

2022-05-18 22:26:05 字數 3561 閱讀 7442

目錄總結

以下內容基於python 3x

涉及的知識前提

函式註解可以針對函式的引數、返回值新增元資料,其為註解。

python是動態語言,變數賦值時不會強制宣告型別,且能隨時重新賦值。無法像靜態編譯型語言一樣,在編譯時發現基本問題。

函式的引數要求,沒有詳細的doc string或更新沒跟上,以至後續的使用者不能夠清晰明白設計者要求的引數型別。以上行為導致的出錯率變高,難以使用等問題。

函式註解可以對引數的要求型別進行註解,對函式返回值進行註解;其只是對做乙個輔助性的說明,並不強制進行型別檢查

一些第三方工具(pycharm)會對已定義的函式註解進行檢查標記提示等,在編寫**時同樣也可以通過編寫乙個裝飾器,來進行一些檢查。

註解資訊儲存在函式的__annotations__屬性中,函式的引數檢查,一定是在函式實際執行之前,檢查傳遞進來的形參與原有的註解型別是否匹配。

__annotations__屬性是乙個字典,對於位置引數的判斷,較為複雜,可直接使用inspect模組獲取函式簽名資訊。

# 註解x和y引數要求為int型別,返回結果為int型別

# syntax:

def foo(x: int, y: int) -> int:

return x + y

檢視其__annotations__屬性資訊:

def foo(x: int, y: int) -> int:

return x + y

print(type(foo.__annotations__))

print(foo.__annotations__)

# 輸出結果:

使用inspect模組獲取簽名資訊:

inspect.signature返回的是乙個ordereddict(有序字典)

import inspect

def foo(x: int, y: int) -> int:

return x + y

sig = inspect.signature(foo)

print(sig.parameters)

# 輸出結果:

ordereddict([('x', ), ('y', )])

使用parameter方法,獲取更詳細的資訊:

import inspect

def foo(x: int , y: int, z=20) -> int:

return x + y + z

sig = inspect.signature(foo)

par = sig.parameters

print(par.items())

print(par["x"].name, "|-|", par["x"].annotation, "|-|", par["x"].default, "|-|", par["x"].empty, "|-|", par["x"].kind)

print(par["y"].name, "|-|", par["y"].annotation, "|-|", par["y"].default, "|-|", par["y"].empty, "|-|", par["y"].kind)

print(par["z"].name, "|-|", par["z"].annotation, "|-|", par["z"].default, "|-|", par["z"].empty, "|-|", par["z"].kind)

#輸出結果:

odict_items([('x', ), ('y', ), ('z', )])

x |-| |-| |-| |-| positional_or_keyword

y |-| |-| |-| |-| positional_or_keyword

z |-| |-| 20 |-| |-| positional_or_keyword

parameter輸出結果的資訊儲存在元組中,唯讀;

name:獲取引數名字;

annotation:獲取引數的註解,有可能沒有定義,則為_empty;

default:返回引數的預設值,如其中z引數的20即為預設值;

empty:特殊的類,用來標記default屬性或者注釋annotation屬性的空值;

kind:實參如何繫結到形參。以下是形參的型別:

了解以上方法後,編寫乙個函式裝飾器用來檢測傳參是否規範。

import inspect

import functools

def parameter_check(fn):

@functools.wraps(fn)

sig = inspect.signature(fn)

parameter = sig.parameters

value = list(parameter.values())

for i, par in enumerate(args):

if value[i].annotation is not value[i].empty and not isinstance(par, value[i].annotation):

raise typeerror("parameter type error")

for k, v in kwargs.items():

if parameter[k].annotation is not parameter[k].empty and not isinstance(v, parameter[k].annotation):

raise typeerror("parameter type error")

ret = fn(*args, **kwargs)

return ret

@parameter_check

def foo(x: int, y: int, z=20) -> int:

return x + y + z

print(foo(1, 50, 29))

# 輸出結果:

80# 更改傳參,檢視效果:

print(foo("hhh", 50, 29))

# 輸出結果:

traceback (most recent call last):

file "e:/project/python/test.py", line 29, in print(foo("hhh", 50, 29))

raise typeerror("parameter type error")

typeerror: parameter type error

通過對函式註解的了解,能夠更加規範**,提高效率,避免出錯。在實際應用中亦可方便的展開使用。

Python 函式註解

start 當我們定義函式的時候,引數是不需要指定型別的,如果你要呼叫別人寫的函式,而該函式又沒有文件說明,你如何知道要傳遞什麼型別的引數呢?也需只能看源 了。好在 python 還提供了一種機制,可以在定義函式的同時指定引數型別,稱之為函式註解。def f name str,age int 18 ...

Python基礎 函式註解

用於為函式宣告中的引數和返回值附加元資料 乙個有註解的clip函式 def clip text str,max len int 0 80 str 函式註解 在max len前面或後面的第乙個空格處截斷文字 end none iflen text max len space before text.r...

Python3 函式註解

python3提供一種語法,用於為函式宣告中的引數和返回值附加元資料。下面的例子是註解後的版本,特點在第一行 1 def clip text str,max len int 0 80 str 2 在max len前面或後面的第乙個空格處截斷文字 3 4 end none 5 if len text ...