博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
检查python模块_Python输入模块–有效使用类型检查器
阅读量:2533 次
发布时间:2019-05-11

本文共 9376 字,大约阅读时间需要 31 分钟。

检查python模块

Introduced since Python 3.5, Python’s typing attempts to provide a way of hinting types to help static type checkers and linters accurately predict errors.

从Python 3.5开始引入,Python的键入 尝试提供一种提示类型的方法,以帮助静态类型检查器和linters准确地预测错误。

Due to Python having to determine the type of objects during run-time, it sometimes gets very hard for developers to find out what exactly is going on in the code.

由于Python必须在运行时确定对象的类型,因此开发人员有时很难找出代码中到底发生了什么。

Even external type checkers like PyCharm IDE do not produce the best results; on average only predicting errors correctly about 50% of the time, according to answer on StackOverflow.

即使像PyCharm IDE这样的外部类型检查器也无法产生最佳结果。 平均只有正确预测约50%的时间误差,根据答案在计算器上。

Python attempts to mitigate this problem by introducing what is known as type hinting (type annotation) to help external type checkers identify any errors. This is a good way for the programmer to hint the type of the object(s) being used, during compilation time itself and ensure that the type checkers work correctly.

Python尝试通过引入所谓的类型提示 (类型注释)来缓解这种问题,以帮助外部类型检查器识别任何错误。 对于程序员来说,这是在编译期间暗示所使用对象类型的好方法,并确保类型检查器正常工作。

This makes Python code much more readable and robust as well, to other readers!

对于其他读者来说,这也使得Python代码更具可读性和鲁棒性!

NOTE: This does not do actual type checking at compile time. If the actual object returned was not of the same type as hinted, there will be no compilation error. This is why we use external type checkers, such as to identify any type errors.

:此并不做实际的类型在编译时检查。 如果作为暗示返回的实际对象是同一类型的没有, 也不会有编译错误。 这就是为什么我们使用外部类型检查器(例如来识别任何类型错误的原因。



建议的先决条件 (Recommended Prerequisites)

For using the typing module effectively, it is recommended that you use an external type checker/linter to check for static type matching. One of the most widely used type checkers in use for Python is , so I recommend that you install it before reading the rest of the article.

为了有效使用typing模块,建议您使用外部类型检查器/衬纸检查静态类型匹配。 用于Python的最广泛使用的类型检查器之一是 ,因此建议您在阅读本文其余部分之前先安装它。

We have already covered the basics of . You can go through this article first.

我们已经介绍了中的基础。 您可以先阅读本文。

We will be using mypy as the static type checker in this article, which can be installed by:

我们将在本文mypy用作静态类型检查器,可以通过以下方式安装它:

pip3 install mypy

You can run mypy to any Python file to check if the types match. This is as if you are ‘compiling’ Python code.

您可以将mypy运行到任何Python文件中,以检查类型是否匹配。 就像您正在“编译” Python代码一样。

mypy program.py

After debugging errors, you can run the program normally using:

调试错误后,可以使用以下命令正常运行该程序:

python program.py

Now that we have our prerequisites covered, let’s try to use some of the module’s features.

现在我们已经满足了先决条件,让我们尝试使用该模块的某些功能。



类型提示/类型注释 (Type Hints / Type Annotations)

关于功能 (On functions)

We can annotate a function to specify its return type and the types of its parameters.

我们可以注释一个函数以指定其返回类型及其参数的类型。

def print_list(a: list) -> None:    print(a)

This informs the type checker (mypy in my case) that we have a function print_list(), that will take a list as an argument and return None.

这将通知类型检查器(在我的情况下为mypy )我们有一个函数print_list() ,该函数将list作为参数并返回None

def print_list(a: list) -> None:    print(a)print_list([1, 2, 3])print_list(1)

Let’s run this on our type checker mypy first:

首先让我们在类型检查器mypy上运行它:

vijay@JournalDev:~ $ mypy printlist.py printlist.py:5: error: Argument 1 to "print_list" has incompatible type "int"; expected "List[Any]"Found 1 error in 1 file (checked 1 source file)

As expected, we get an error; since the line #5 has the argument as an int, rather than a list.

不出所料,我们得到一个错误; 因为第5行的参数为int而不是list

关于变量 (On Variables)

Since Python 3.6, we can also annotate the types of variables, mentioning the type. But this is not compulsory if you want the type of a variable to change before the function returns.

从Python 3.6开始,我们还可以注释变量的类型,并提及类型。 但这不是强制性的,如果您希望在函数返回之前更改变量的类型。

# Annotates 'radius' to be a floatradius: float = 1.5# We can annotate a variable without assigning a value!sample: int# Annotates 'area' to return a floatdef area(r: float) -> float:    return 3.1415 * r * rprint(area(radius))# Print all annotations of the function using# the '__annotations__' dictionaryprint('Dictionary of Annotations for area():', area.__annotations__)

Output of mypy:

mypy的输出

vijay@JournalDev: ~ $ mypy find_area.py && python find_area.pySuccess: no issues found in 1 source file7.068375Dictionary of Annotations for area(): {'r': 
, 'return':
}

This is the recommended way to use mypy, first providing type annotations, before using the type checker.

建议使用mypy ,首先使用类型注释,然后再使用类型检查器。



类型别名 (Type Aliases)

The typing module provides us with Type Aliases, which is defined by assigning a type to the alias.

typing模块为我们提供了Type Aliases ,它是通过为别名分配类型来定义的。

from typing import List# Vector is a list of float valuesVector = List[float]def scale(scalar: float, vector: Vector) -> Vector:    return [scalar * num for num in vector]a = scale(scalar=2.0, vector=[1.0, 2.0, 3.0])print(a)

Output

输出量

vijay@JournalDev: ~ $ mypy vector_scale.py && python vector_scale.pySuccess: no issues found in 1 source file[2.0, 4.0, 6.0]

In the above snippet, Vector is an alias, which stands for a list of floating point values. We can type hint at an alias, which is what the above program is doing.

在上面的代码段中, Vector是一个别名,代表浮点值的列表。 我们可以在别名上键入提示,这就是上面程序的作用。

The complete list of acceptable aliases is given .

提供可接受别名的完整列表。

Let’s look at one more example, which checks every key:value pair in a dictionary and check if they match the name:email format.

让我们再看一个示例,该示例检查字典中的每个key:value对,并检查它们是否与name:email格式匹配。

from typing import Dictimport re# Create an alias called 'ContactDict'ContactDict = Dict[str, str]def check_if_valid(contacts: ContactDict) -> bool:    for name, email in contacts.items():        # Check if name and email are strings        if (not isinstance(name, str)) or (not isinstance(email, str)):            return False        # Check for email xxx@yyy.zzz        if not re.match(r"[a-zA-Z0-9\._\+-]+@[a-zA-Z0-9\._-]+\.[a-zA-Z]+$", email):            return False    return Trueprint(check_if_valid({'vijay': 'vijay@sample.com'}))print(check_if_valid({'vijay': 'vijay@sample.com', 123: 'wrong@name.com'}))

Output from mypy

mypy的输出

vijay@JournalDev:~ $ mypy validcontacts.py validcontacts.py:19: error: Dict entry 1 has incompatible type "int": "str"; expected "str": "str"Found 1 error in 1 file (checked 1 source file)

Here, we get a static compile time error in mypy, since the name parameter on our second dictionary is an integer (123). Thus, aliases are another way to enforce accurate type checking from mypy.

在这里,由于第二个字典上的name参数是一个整数( 123 ),因此mypy出现了静态编译时错误。 因此,别名是从mypy强制进行准确类型检查的另一种方法。



使用NewType()创建用户定义的数据类型 (Create user defined datatypes using NewType())

We can use the NewType() function to create new user defined types.

我们可以使用NewType()函数来创建新的用户定义类型。

from typing import NewType# Create a new user type called 'StudentID' that consists of# an integerStudentID = NewType('StudentID', int)sample_id = StudentID(100)

The static type checker will treat the new type as if it were a subclass of the original type. This is useful in helping catch logical errors.

静态类型检查器会将新类型视为原始类型的子类。 这有助于帮助捕获逻辑错误。

from typing import NewType# Create a new user type called 'StudentID'StudentID = NewType('StudentID', int)def get_student_name(stud_id: StudentID) -> str:    return str(input(f'Enter username for ID #{stud_id}:\n'))stud_a = get_student_name(StudentID(100))print(stud_a)# This is incorrect!!stud_b = get_student_name(-1)print(stud_b)

Output from mypy

mypy的 输出

vijay@JournalDev:~ $ mypy studentnames.py  studentnames.py:13: error: Argument 1 to "get_student_name" has incompatible type "int"; expected "StudentID"Found 1 error in 1 file (checked 1 source file)


任何类型 (The Any type)

This is a special type, informing the static type checker (mypy in my case) that every type is compatible with this keyword.

这是一种特殊类型,通知静态类型检查器(在我的情况下为mypy )每个类型都与此关键字兼容。

Consider our old print_list() function, now accepting arguments of any type.

考虑我们以前的print_list()函数,现在接受任何类型的参数。

from typing import Anydef print_list(a: Any) -> None:    print(a)print_list([1, 2, 3])print_list(1)

Now, there will be no errors when we run mypy.

现在,运行mypy不会有任何错误。

vijay@JournalDev:~ $ mypy printlist.py && python printlist.pySuccess: no issues found in 1 source file[1, 2, 3]1

All functions without a return type or parameter types will implicitly default to using Any.

所有没有返回类型或参数类型的函数都将默认使用Any

def foo(bar):    return bar# A static type checker will treat the above# as having the same signature as:def foo(bar: Any) -> Any:    return bar

You can thus use Any to mix up statically and dynamically typed code.

因此,您可以使用Any混合静态和动态类型的代码。



结论 (Conclusion)

In this article, we have learned about the Python typing module, which is very useful in the context of type checking, allowing external type checkers like mypy to accurately report any errors.

在本文中,我们了解了Python 类型模块,该模块在类型检查的上下文中非常有用,它允许像mypy这样的外部类型检查器准确报告任何错误。

This provides us with a way to write statically typed code in Python, which is a dynamically typed language by design!

这为我们提供了一种使用Python编写静态类型代码的方法,这是一种设计成动态类型的语言!



参考资料 (References)

  • (This contains extensive detail on more methods in this module, and I recommend this as a secondary reference)

    (包含有关该模块中更多方法的大量详细信息,我建议将此作为辅助参考)
  • (This provides a very good discussion on the topic. I highly recommend you to read this topic as well!)

    (这提供了关于该主题的很好的讨论。我强烈建议您也阅读该主题!)


翻译自:

检查python模块

转载地址:http://oqlzd.baihongyu.com/

你可能感兴趣的文章
Android ListView上拉获取下一页
查看>>
算法练习题
查看>>
学习使用Django一 安装虚拟环境
查看>>
Hibernate视频学习笔记(8)Lazy策略
查看>>
CSS3 结构性伪类选择器(1)
查看>>
IOS 杂笔-14(被人遗忘的owner)
查看>>
自动测试用工具
查看>>
前端基础之BOM和DOM
查看>>
[T-ARA/筷子兄弟][Little Apple]
查看>>
编译Libgdiplus遇到的问题
查看>>
【NOIP 模拟赛】Evensgn 剪树枝 树形dp
查看>>
java学习笔记④MySql数据库--01/02 database table 数据的增删改
查看>>
两台电脑如何实现共享文件
查看>>
组合模式Composite
查看>>
程序员最想得到的十大证件,你最想得到哪个?
查看>>
我的第一篇CBBLOGS博客
查看>>
【MyBean调试笔记】接口的使用和清理
查看>>
07 js自定义函数
查看>>
jQueru中数据交换格式XML和JSON对比
查看>>
form表单序列化后的数据转json对象
查看>>