python代码查找
TL;DR — If you’re working on a large Python project or just like to keep your code-base tidy and neat, Pytype is the tool for you.
TL; DR —如果您正在从事大型Python项目,或者只是想保持代码库整洁, Pytype是您的工具。
Python is a great programming language for prototyping and scripting. The concise syntax, flexible type system, and interpreted nature allows us to quickly try an idea, tweak it, and try again.
Python是用于原型设计和脚本编写的出色编程语言。 简洁的语法,灵活的类型系统和解释的性质使我们能够快速尝试一个想法,对其进行调整,然后再试一次。
When Python projects grow, the flexibility that was once an enabler for speed becomes a burden on development velocity. As additional developers join the project, and more code is written, the lack of type information makes it harder to read and understand the code. Without a type-checking system, mistakes are easy to make and hard to catch.
当Python项目增长时 ,曾经是速度的推动力的灵活性已成为开发速度的负担。 随着更多的开发人员加入该项目,并且编写了更多的代码,缺少类型信息使得阅读和理解代码变得更加困难。 如果没有类型检查系统,那么错误很容易发生并且很难发现。
Pytype to the rescue! Pytype is an open-source tool for type checking and type inference in Python. And it works out-of-the-box — just install and run!
抢救Pytype ! Pytype是一个用于在Python中进行类型检查和类型推断的开源工具。 它开箱即用-只需安装并运行!
Pytype will…
Pytype会...
Merge back inferred type information into your code, if you want.
如果需要 ,将推断的类型信息合并回您的代码中。
If you’re sold, go ahead and visit Pytype for installation and usage instructions. Below I present some cool usage examples!
如果您被出售,请继续并访问Pytype以获取安装和使用说明。 下面我提供一些很酷的用法示例!
This is the most common scenario. You wrote some code and want to sanity-check that you didn’t make any mistakes. Consider this function:
这是最常见的情况。 您编写了一些代码,并想进行完整性检查以确保您没有犯任何错误。 考虑以下功能:
import re
def GetUsername(email_address):
match = re.match(r'([^@]+)@example\.com', email_address)
return match.group(1)
Pretty straightforward. It extracts the part of an email address before the @ using a regular expression, and returns it. Did you notice the bug?
非常简单。 它使用正则表达式提取电子邮件地址中@之前的部分,并将其返回。 您注意到错误了吗?
Let’s see what happens when we use pytype
to check it:
让我们看看使用pytype
进行检查时会发生什么:
% pytype get_username.py
Analyzing 1 sources with 0 dependencies
File "/.../get_username.py",
line 5, in GetUsername: No attribute 'group' on None [attribute-error]
In Optional[Match[str]]
Pytype tells us that group
is not a valid function call on match
. Oh! re.match()
returns None
when no match is found. Indeed, in these cases match.group(1)
will throw an exception.
Pytype告诉我们group
不是match
上的有效函数调用。 哦! 如果找不到匹配项,则re.match()
返回None
。 实际上,在这些情况下, match.group(1)
将引发异常。
Let’s fix the bug, by having the function return None for an invalid email address:
让我们通过使函数为无效的电子邮件地址返回None来修复该错误:
import re
def GetUsername(email_address):
match = re.match(r'([^@]+)@example\.com', email_address)
if match is None:
return None
return match.group(1) # <-- Here, match can't be None
Now, when we re-run pytype
, the error is gone. Pytype infers that if the code after the if gets executed, match is guaranteed not to be None
.
现在,当我们重新运行pytype
,错误消失了。 Pytype推断,如果执行if之后的代码,则保证match不为None
。
In Python 3, you can type-annotate (PEP 484) your code to help type-checking tools and other developers understand your intention. Pytype is able to alert when your type annotations have mistakes:
在Python 3中,您可以对代码进行类型注释( PEP 484 ),以帮助类型检查工具和其他开发人员理解您的意图。 当您的类型注释有错误时,Pytype能够发出警报:
import re
from typing import Match
def GetEmailMatch(email) -> Match:
return re.match(r'([^@]+)@example\.com', email)
Let’s use pytype
to check this code snippet:
让我们使用pytype
来检查以下代码片段:
% pytype example.py
Analyzing 1 sources with 0 dependencies
File "/.../example.py", line 5, in GetEmailMatch:
bad option in return type [bad-return-type]
Expected: Match
Actually returned: None
Pytype is telling us that GetEmailMatch
might return None
, but we annotated its return type as Match
. To fix this, we can use the Optional
type annotation from the typing module:
Pytype告诉我们GetEmailMatch
可能返回None
,但是我们将其返回类型注释为Match
。 为了解决这个问题,我们可以使用打字模块中的Optional
类型注释:
import re
from typing import Match, Optional
def GetEmailMatch(email) -> Optional[Match]:
return re.match(r'([^@]+)@example\.com', email)
Optional
means that the return value can be a Match
object or None
.
Optional
表示返回值可以是Match
对象或None
。
To help you adopt type annotations, Pytype can add them into the code for you. Let’s look at this code snippet:
为了帮助您采用类型注释,Pytype可以将它们添加到您的代码中。 让我们看一下以下代码片段:
import re
def GetEmailMatch(email):
return re.match(r'([^@]+)@example\.com', email)
def GetUsername(email_address):
match = GetEmailMatch(email_address)
if match is None:
return None
return match.group(1)
To add type annotations to this code, we first run pytype
on the file. pytype
saves the inferred type information into a .pyi
file. Then, we can run merge-pyi
to merge the type annotations back into the code:
要将类型注释添加到此代码中,我们首先在文件上运行pytype
。 pytype
将推断的类型信息保存到.pyi
文件中。 然后,我们可以运行merge-pyi
将类型注释合并回代码中:
% pytype email.py
% merge-pyi -i email.py pytype_output/email.pyi
And voilà!
和瞧!
import re
from typing import Match
from typing import Optional
def GetEmailMatch(email) -> Optional[Match[str]]:
return re.match(r'([^@]+)@example\.com', email)
def GetUsername(email_address) -> Optional[str]:
match = GetEmailMatch(email_address)
if match is None:
return None
return match.group(1)
The type annotations, including import
statements, are now in the source file.
类型注释,包括import
语句,现在位于源文件中。
For more usage examples and installation instructions, please visit Pytype on GitHub.
有关更多用法示例和安装说明,请访问GitHub上的Pytype 。
Thanks for reading!
谢谢阅读!
python代码查找