python的mag模块_Python全栈-magedu-2018-笔记22
第十五章 - Python 類型注解
函數定義的弊端
Python是動態語言,變量隨時可以被賦值,且能賦值為不同的類型
Python不是靜態編譯型語言,變量類型是在運行器決定的
動態語言很靈活,但是這種特性也是弊端
def add(x, y):
return x + y
print(add(4, 5))
print(add('hello', 'world'))
add(4, 'hello') #
難發現:由于不做任何類型檢查,直到運行期問題才顯現出來,或者線上運行時才能暴露出問題
難使用:函數的使用者看到函數的時候,并不知道你的函數的設計,并不知道應該傳入什么類型的數據
函數定義的弊端
如何解決這種動態語言定義的弊端呢?
增加文檔Documentation String
這只是一個慣例,不是強制標準,不能要求程序員一定為函數提供說明文檔
函數定義更新了,文檔未必同步更新
def add(x, y):
'''
:param x: int
:param y: int
:return: int
'''
return x + y
print(help(add))
函數注解Function Annotations
如果解決這種動態語言定義的弊端呢?
函數注解
def add(x:int , y:int) -> int :
'''
:param x: int
:param y: int
:return: int
'''
return x + y
print(help(add))
print(add(4, 5))
print(add('mag', 'edu'))
函數注解Function Annotations
函數注解
Python 3.5引入
對函數的參數進行類型注解
對函數的返回值進行類型注解
只對函數參數做一個輔助的說明,并不對函數參數進行類型檢查
提供給第三方工具,做代碼分析,發現隱藏的bug
函數注解的信息,保存在__annotations__屬性中
add.__annotations__
{'x': , 'y': , 'return': }
變量注解
Python 3.6引入
i : int = 3
業務應用
函數參數類型檢查
思路
函數參數的檢查,一定是在函數外
函數應該作為參數,傳入到檢查函數中
檢查函數拿到函數傳入的實際參數,與形參聲明對比
__annotations__屬性是一個字典,其中包括返回值類型的聲明。假設要做位置參數的判斷,無法和字典中的聲明對應。使用inspect模塊
inspet模塊
提供獲取對象信息的函數,可以檢查函數和類、類型檢查
inspect模塊
signature(callable),獲取簽名(函數簽名包含了一個函數的信息,包括函數名、它的參數類型、它所在的類和名稱空間及其他信息)
import inspect
def add(x:int, y:int, *args,**kwargs) -> int:
return x + y
sig = inspect.signature(add)
print(sig, type(sig)) # 函數簽名
print('params : ', sig.parameters) # OrderedDict
print('return : ', sig.return_annotation)
print(sig.parameters['y'], type(sig.parameters['y']))
print(sig.parameters['x'].annotation)
print(sig.parameters['args'])
print(sig.parameters['args'].annotation)
print(sig.parameters['kwargs'])
print(sig.parameters['kwargs'].annotation)
inspect模塊
inspect.isfunction(add),是否是函數
inspect.ismethod(add)),是否是類的方法
inspect.isgenerator(add)),是否是生成器對象
inspect.isgeneratorfunction(add)),是否是生成器函數
inspect.isclass(add)),是否是類
inspect.ismodule(inspect)),是否是模塊
inspect.isbuiltin(print)),是否是內建對象
還有很多is函數,需要的時候查閱inspect模塊幫助
inspect模塊
Parameter對象
保存在元組中,是只讀的
name,參數的名字
annotation,參數的注解,可能沒有定義
default,參數的缺省值,可能沒有定義
empty,特殊的類,用來標記default屬性或者注釋annotation屬性的空值
kind,實參如何綁定到形參,就是形參的類型
POSITIONAL_ONLY,值必須是位置參數提供
POSITIONAL_OR_KEYWORD,值可以作為關鍵字或者位置參數提供
VAR_POSITIONAL,可變位置參數,對應*args
KEYWORD_ONLY,keyword-only參數,對應*或者*args之后的出現的非可變關鍵字參數
VAR_KEYWORD,可變關鍵字參數,對應**kwargs
inspect模塊
舉例
import inspect
def add(x, y:int=7, *args, z, t=10,**kwargs) -> int:
return x + y
sig = inspect.signature(add)
print(sig)
print('params : ', sig.parameters) # 有序字典
print('return : ', sig.return_annotation)
print('~~~~~~~~~~~~~~~~')
for i, item in enumerate(sig.parameters.items()):
name, param = item
print(i+1, name, param.annotation, param.kind, param.default)
print(param.default is param.empty, end='\n\n')
業務應用
有函數如下
def add(x, y:int=7) -> int:
return x + y
請檢查用戶輸入是否符合參數注解的要求?
業務應用
有函數如下
def add(x, y:int=7) -> int:
return x + y
請檢查用戶輸入是否符合參數注解的要求?
思路
調用時,判斷用戶輸入的實參是否符合要求
調用時,用戶感覺上還是在調用add函數
對用戶輸入的數據和聲明的類型進行對比,如果不符合,提示用戶
業務應用
import inspect
def add(x, y:int=7) -> int:
return x + y
def check(fn):
def wrapper(*args, **kwargs):
sig = inspect.signature(fn)
params = sig.parameters
values = list(params.values())
for i,p in enumerate(args):
if isinstance(p, values[i].annotation): # 實參和形參聲明一致
print('')
for k,v in kwargs.items():
if isinstance(v, params[k].annotation): # 實參和形參聲明一致
print('=')
return fn(*args, **kwargs)
return wrapp
調用測試
check(add)(20,10)
check(add)(20,y=10)
check(add)(y=10,x=20)
業務需求是參數有注解就要求實參類型和聲明應該一致,沒有注解的參數不比較,如何修改代碼?
業務應用
import inspect
def check(fn):
def wrapper(*args, **kwargs):
sig = inspect.signature(fn)
params = sig.parameters
values = list(params.values())
for i,p in enumerate(args):
param = values[i]
if param.annotation is not param.empty and not isinstance(p, param.annotation):
print(p,'!',values[i].annotation)
for k,v in kwargs.items():
if params[k].annotation is not inspect._empty and not isinstance(v, params[k].annotation):
print(k,v,'!=',params[k].annotation)
return fn(*args, **kwargs)
return wrapper
@check
def add(x, y:int=7) -> int:
return x + y
調用測試
add(20,10)
add(20,y=10)
add(y=10,x=20)
最后
總結
以上是生活随笔為你收集整理的python的mag模块_Python全栈-magedu-2018-笔记22的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 联想电脑怎么启动系统u盘 联想电脑如何使
- 下一篇: 笔记本怎么进不了pe 笔记本无法引导PE