多平台统一管理软件接口,如何实现多平台统一管理软件接口
912
2022-08-28
python之声明函数时指定传入参数的数据类型 || 函数return返回值的数据类型(函数参数的注释以及函数返回值的注释)|| python之内置typing模块:类型提示支持(python函数怎么传递参数)
前言:
①在 Python 3.5 中,Python PEP 484 引入了类型注解(type hints),在 Python 3.6 中,PEP 526 又进一步引入了变量注解(Variable Annotations)。
②具体的变量注解语法可以归纳为两点:
③在PEP 8 中,具体的格式是这样规定的:
④值得注意的是,这种类型和变量注解实际上只是一种类型提示,对运行实际上是没有影响的。
⑤另外也有一些库是支持类型检查的,比如 mypy,安装之后,利用 mypy 即可检查出 Python 脚本中不符合类型注解的调用情况。
注解表达式
当你自己写的函数或方法,要被其他人调用时,如果你想让对方知道函数或方法传入参数的数据类型,可以这样定义:
def demo(name: str, age: 'int > 0' = 20) -> str: # ->str 表示该函数的返回值是str类型的 print(name, type(name)) print(age, type(age)) return "hello world"if __name__ == '__main__': demo(1, 2) # 这里的参数1会显示黄色, 但是可以运行不会报错 demo('小小', 2) # 正常显示
运行结果:
总结:
①以上是注解表达式的应用方法,注解中最常用的就是类( str 或 int )类型和字符串(如 'int>0' )。
②对于注解python不会做任何处理,它只是存储在函数的 __annotations__ 属性(字典)中 【其中包括函数入参参数的注解以及函数 return 返回的值的注解】
③对于注解,python不做检查, 不做强制,,不做验证, 什么操作都不做。
④换而言之,,注释对python解释器没有任何意义, 只是为了方便使用函数的人。
指定传入参数的数据类型为any
代码如下:
def demo(name: any, age: 'int > 0' = 20) -> str: # ->str 表示该函数的返回值是str类型的 print(name, type(name)) print(age, type(age)) return "hello world"if __name__ == '__main__': demo(name=1, age=2) # 正常显示 demo(name='小小', age=2) # 正常显示
运行结果:
函数参数注解
代码如下:
def demo(name: str, age: 'int > 0' = 20) -> str: # ->str 表示该函数的返回值是str类型的 print(name, type(name)) print(age, type(age)) return "hello world"if __name__ == '__main__': print(demo.__annotations__)
解释:demo函数的参数注解存放在 __annotations__ 字典中。
运行结果:
{'name':
1、typing介绍
Python是一门弱类型的语言,很多时候我们可能不清楚函数参数的类型或者返回值的类型,这样会导致我们在写完代码一段时间后回过头再看代码,忘记了自己写的函数需要传什么类型的参数,返回什么类型的结果,这样就不得不去阅读代码的具体内容,降低了阅读的速度, typing 模块可以很好的解决这个问题。
【注意】: typing 模块只有在python3.5以上的版本中才可以使用,pycharm目前支持 typing 检查。
2、typing的作用
类型检查,防止运行时出现参数和返回值类型不符合。作为开发文档附加说明,方便使用者调用时传入和返回参数类型。该模块加入后并不会影响程序的运行,不会报正式的错误,只有提醒pycharm目前支持typing检查,参数类型错误会黄色提示
3、常用数据类型
int,long,float: 整型,长整形,浮点型;bool,str: 布尔型,字符串类型;List,Tuple,Dict,Set:列表,元组,字典, 集合;Iterable,Iterator:可迭代类型,迭代器类型;Generator:生成器类型;
除了以上常用的类型,还支持 Any , Union , Tuple , Callable , TypeVar 和 Generic 类型组成。有关完整的规范,请参阅 PEP 484 。有关类型提示的简单介绍,请参阅 PEP 483
4、代码示例
func函数要求传入的第2个参数为 str 类型,而我们调用时传入的参数是 int 类型,此时Pycharm就会用黄色来警告你,我们将光标放到黄色的地方,会出现下面的提示:
写着期望类型是 str ,而现在是 int ,但是 typing的作用仅仅是提示,并不会影响代码执行;
执行结果如下:我们会发现并没有报错,因为 typing仅仅是起到了提醒的作用。
[2, 3]
5、类型别名
类型别名,就是给复杂的类型取个别名
# 给List[float]类型取个别名为VectorVector = List[float]def scale(scalar: float, vector: Vector) -> Vector: return [scalar * num for num in vector]new_vector = scale(2.0, [1.0, -4.2, 5.4])
当然,类型别名我们完全可以不用,用以下写法也一样,看个人喜好
def scale(scalar: float, vector: List[float]) -> List[float]: return [scalar * num for num in vector]
6、typing 模块中包含的数据类型
AbstractSet = typing.AbstractSetAny = typing.AnyAnyStr = ~AnyStrAsyncContextManager = typing.AbstractAsyncContextManagerAsyncGenerator = typing.AsyncGeneratorAsyncIterable = typing.AsyncIterableAsyncIterator = typing.AsyncIteratorAwaitable = typing.AwaitableByteString = typing.ByteStringCallable = typing.CallableClassVar = typing.ClassVarCollection = typing.CollectionContainer = typing.ContainerContextManager = typing.AbstractContextManagerCoroutine = typing.CoroutineCounter = typing.CounterDefaultDict = typing.DefaultDictDeque = typing.DequeDict = typing.DictFrozenSet = typing.FrozenSetGenerator = typing.GeneratorHashable = typing.HashableItemsView = typing.ItemsViewIterable = typing.IterableIterator = typing.IteratorKeysView = typing.KeysViewList = typing.ListMapping = typing.MappingMappingView = typing.MappingViewMutableMapping = typing.MutableMappingMutableSequence = typing.MutableSequenceMutableSet = typing.MutableSetNoReturn = typing.NoReturnOptional = typing.OptionalReversible = typing.ReversibleSequence = typing.SequenceSet = typing.SetSized = typing.SizedTYPE_CHECKING = FalseTuple = typing.TupleType = typing.TypeUnion = typing.UnionValuesView = typing.ValuesView
前言
names: list = ['Germey', 'Guido']version: tuple = (3, 7, 4)operations: dict = {'show': False, 'sort': True}
比如我们只通过类型注解是不知道 names 里面的元素是什么类型的,只知道 names 是一个列表 list 类型,实际上里面都是字符串 str 类型。
from typing import List, Tuple, Dictnames: List[str] = ['Germey', 'Guido']version: Tuple[int, int, int] = (3, 7, 4)operations: Dict[str, bool] = {'show': False, 'sort': True}
这样一来,变量的类型便可以非常直观地体现出来。
④目前 typing 模块也已经被加入到 Python 标准库中,不需要安装第三方模块就可以直接使用。
typing模块的具体用法
①在引入的时候就直接通过 typing 模块引入
例如:
from typing import List, Tuple
②List
var: List[int or float] = [2, 3.5]
var: List[List[int]] = [[1, 2], [2, 3]]
【注意】因为容器中的元素的类型信息由于泛型不同,通过一般方式静态推断,因此抽象类被用来拓展表示容器中的元素。
③Tuple、NamedTuple
person: Tuple[str, int, float] = ('Mike', 22, 1.75)
同样地也可以使用类型嵌套:
④Dict、Mapping、MutableMapping
Dict,字典,是 dict 的泛型;
Mapping,映射,是 collections.abc.Mapping 的泛型。
def size(rect: Mapping[str, int]) -> Dict[str, int]: return {'width': rect['width'] + 100, 'height': rect['width'] + 100}
这里将 Dict 用作了返回值类型注解,将 Mapping 用作了参数类型注解。
MutableMapping 则是 Mapping 对象的子类,在很多库中也经常用 MutableMapping 来代替 Mapping。
⑤Set、AbstractSet
Set,集合,是 set 的泛型;
AbstractSet,是 collections.abc.Set 的泛型。
def describe(s: AbstractSet[int]) -> Set[int]: return set(s)
这里将 Set 用作了返回值类型注解,将 AbstractSet 用作了参数类型注解。
⑥Sequence
Sequence,是 collections.abc.Sequence 的泛型。
在某些情况下,我们可能并不需要严格区分一个变量或参数到底是列表 list 类型还是元组 tuple 类型,我们可以使用一个更为泛化的类型,叫做 Sequence,其用法类似于 List,如:
def square(elements: Sequence[float]) -> List[float]: return [x ** 2 for x in elements]
⑦NoReturn
NoReturn,当一个方法没有返回值时,为了注解它的返回类型,我们可以将其注解为 NoReturn,例如:
def hello() -> NoReturn: print('hello')
⑧Any
Any,是一种特殊的类型,它可以代表所有类型,静态类型检查器的所有类型都与 Any 类型兼容;
所有的无参数类型注解和无返回类型注解的都会默认使用 Any 类型。
def add(a): return a + 1def add(a: Any) -> Any: return a + 1
原理类似于 object,所有的类型都是 object 的子类。
⑨TypeVar
height = 1.75Height = TypeVar('Height', int, float, None)def get_height() -> Height: return height
⑩NewType
Person = NewType('Person', Tuple[str, int, float])person = Person(('Mike', 22, 1.75))
这里实际上 person 就是一个 tuple 类型,我们可以对其像 tuple 一样正常操作。
①①Callable
Callable,可调用类型,它通常用来注解一个方法,比如下面的 add 方法,它就是一个 Callable 类型:
from typing import Callabledef add(a): return a + 1print(Callable, type(add), isinstance(add, Callable), sep='\n')
运行结果:
typing.Callable
在这里虽然二者 add 利用 type 方法得到的结果是 function,但实际上利用 isinstance 方法判断确实是 True。
def date(year: int, month: int, day: int) -> str: return f'{year}-{month}-{day}'def get_date_fn() -> Callable[[int, int, int], str]: return date
①②Union
Union,联合类型,Union[X, Y] 代表要么是 X 类型,要么是 Y 类型。
联合类型的联合类型等价于展平后的类型:
Union[Union[int, str], float] == Union[int, str, float]
仅有一个参数的联合类型会压缩成参数自身,比如:
Union[int] == int
多余的参数会被跳过,比如:
Union[int, str, int] == Union[int, str]
在比较联合类型的时候,参数顺序会被忽略,比如:
Union[int, str] == Union[str, int]
def process(fn: Union[str, Callable]): if isinstance(fn, str): # str2fn and process pass elif isinstance(fn, Callable): fn()
①③Optional
但值得注意的是,这个并不等价于可选参数,当它作为参数类型注解的时候,不代表这个参数可以不传递了,而是说这个参数可以传为 None。
from typing import Optionaldef judge(result: bool) -> Optional[str]: if result: return 'Error Occurred'if __name__ == '__main__': print('当入参result=False时:', judge(result=False)) print('当入参result=True时:', judge(result=True))
执行结果:
①④Generator
from typing import Generatordef echo_round() -> Generator[int, float, str]: sent = yield 0 while sent >= 0: sent = yield round(sent) return 'Done'
在这里 yield 关键字后面紧跟的变量的类型就是 YieldType,yield 返回的结果的类型就是 SendType,最后生成器 return 的内容就是 ReturnType。
当然很多情况下,生成器往往只需要 yield 内容就够了,我们是不需要 SendType 和 ReturnType 的,可以将其设置为空,如:
from typing import Generatordef infinite_stream(start: int) -> Generator[int, None, None]: while True: yield start start += 1
去期待陌生,去拥抱惊喜。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~