阅读seleniumlibrary源码,学习python typing模块

582 阅读4分钟

前言

今日实现操作页面table元素自动化时,看了一下seleniumlibrary 关于table element keywords的实现源码时,学习到了以下知识,在此记录一下

类型建议符

get table cell 关键字源码

image.png

函数定义中,参数后面带了冒号和箭头 这个写法是Python3.5新增加的功能。因为Python不需要像Java一样,在函数定义中规定参数的类型,所以给程序员带来方便的同时,也增加了代码阅读的难度

所以:通过冒号和箭头来表示这个参数的类型以及这个函数返回值的类型。

  • 冒号:官方叫做参数的类型建议符
  • 箭头:叫做函数返回值的类型建议符

引入类型注解的原因

我们知道python是一种动态语言,在声明一个变量时,不需要显示地声明它的类型,因此在我们定义一个方法,传入的参数并不是我们期望的类型,会报错或者得到意想不到的结果,这样就造成了很多不便,特别是一些复杂的方法,如果不借助额外说明,我们就无法理解这个参数到底是什么类型,因此就引入了类型注解,增加代码的可读性

官方说明:www.python.org/dev/peps/pe…

具体的语法是可以归纳为两点:

  • 在声明变量时,变量的后面可以加一个冒号,后面再写上变量的类型,如 int、list 等等。
  • 在声明方法返回值的时候,可以在方法的后面加一个箭头,后面加上返回值的类型,如 int、list 等等。

在 PEP 8 中,具体的格式是这样规定的:

  • 在声明变量类型时,变量后方紧跟一个冒号,冒号后面跟一个空格,再跟上变量的类型。
  • 在声明方法返回值的时候,箭头左边是方法定义,箭头右边是返回值的类型,箭头左右两边都要留有空格 因为它是一种建议和提示,并不能静态的限定类型,传入一个非建议类型的参数,它任然可以执行 比如
def sum(a: int, b: int) ->int:
        return a + b
        
sum("11", "2")   # 你传入字符串也是可以执行的

不过有了类型注解,一些IDE是可以识别出来并提示的

image.png

变量类型的声明

python3.6的pep526则更进一步引入了对变量类型的声明,和在以前我们只能在注释中对变量的类型进行说明

# 使用注释来标明变量类型
primes = []   # type:list[int]
captain = ...   # type:str

class Starship: stats = {} #type:Dict[str,int]

# 类型注解(不止是参数),还可以是变量
primes:List[int] = [] 
captain:str #Note: no initial value 
class Starship: 
stats: ClassVar[Dict[str,int]] = {}

typing

除了默认类型的int、str用于类型注解的类型有哪些呢? typing库便是一个帮助我们实现类型注解的库

类型别名

在下面这个例子中,Vector和List[float]可以视为同义词

from typing import List
Vector = 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])

类型的别名有助于简化一些复杂的类型声明 类型别名有助于简化一些复杂的类型声明

from typing import Dict, Tuple, List

ConnectionOptions = Dict[str, str]
Address = Tuple[str, int]
Server = Tuple[Address, ConnectionOptions]

def broadcast_message(message: str, servers: List[Server]) -> None:
    ...

# The static type checker will treat the previous type signature as
# being exactly equivalent to this one.
def broadcast_message(
        message: str,
        servers: List[Tuple[Tuple[str, int], Dict[str, str]]]) -> None:
    pass

typing中常见定义类型

前面seleniumlibrary 中就用到了typing的union类型

查看typing源码,支持以下类型

__all__ = [
    # Super-special typing primitives.
    'Any',
    'Callable',
    'ClassVar',
    'ForwardRef',
    'Generic',
    'Optional',
    'Tuple',
    'Type',
    'TypeVar',
    'Union',

    # ABCs (from collections.abc).
    'AbstractSet',  # collections.abc.Set.
    'ByteString',
    'Container',
    'ContextManager',
    'Hashable',
    'ItemsView',
    'Iterable',
    'Iterator',
    'KeysView',
    'Mapping',
    'MappingView',
    'MutableMapping',
    'MutableSequence',
    'MutableSet',
    'Sequence',
    'Sized',
    'ValuesView',
    'Awaitable',
    'AsyncIterator',
    'AsyncIterable',
    'Coroutine',
    'Collection',
    'AsyncGenerator',
    'AsyncContextManager',

    # Structural checks, a.k.a. protocols.
    'Reversible',
    'SupportsAbs',
    'SupportsBytes',
    'SupportsComplex',
    'SupportsFloat',
    'SupportsInt',
    'SupportsRound',

    # Concrete collection types.
    'ChainMap',
    'Counter',
    'Deque',
    'Dict',
    'DefaultDict',
    'List',
    'OrderedDict',
    'Set',
    'FrozenSet',
    'NamedTuple',  # Not really a type.
    'Generator',

    # One-off things.
    'AnyStr',
    'cast',
    'get_type_hints',
    'NewType',
    'no_type_check',
    'no_type_check_decorator',
    'NoReturn',
    'overload',
    'Text',
    'TYPE_CHECKING',
]

怎么进行静态类型检查

通过类型注解,类型注释和typing, 我们可以在IDE看到提示,配合使用 mypy 等工具,我们就可以对 Python 代码做静态类型检查了 安装 pip install mypy

使用

image.png