文章目录(Table of Contents)
简介
在写Python代码的时候, 有的时候为了代码更加完善, 我们会在定义函数的时候给出参数的类型, 同时也会格式return的类型, 如下所示:
- def add(a: int, b: int) -> int:
- return a + b
这个时候, 我们可以使用MonkeyType这个库来自动完成. 下面简单介绍一下用法. MonkeyType的Github链接, Github, Instagram-MonkeyType
MonkeyType用法介绍
MonkeyType的安装
- pip install monkeytype
MonkeyType的使用
下面使用一个简单的例子来说明使用方法. 测试文件的结构如下所示:
- D:.
- │─ test.py
- │
- └─some
- ─ addFunction.py
- ─ __init__.py
假设我们写的module叫some
, some
下有一个文件为addFunction.py
, 里面定义了一个实现加法的类. 我们没有定义变量的类型 (一会我们使用MonkeyType自动加上). 定义的类如下所示:
- class add_number(object):
- """这是一个加法运算
- """
- def __init__(self, a, b):
- self.a = a
- self.b = b
- def add_n(self):
- c = self.a + self.b
- return c
为了对add_number
添加相关的变量类型, 我们写一个脚本为test.py
, 其中会调用add_number
. test.py
的内容如下所示, 我们初始化add_number类, 并调用其中的方法:
- from some.addFunction import add_number
- add_number(1,2).add_n()
接着运行test.py
文件, 注意这里使用monkeytype run
运行. 完成的命令如下所示:
- monkeytype run test.py
运行之后会生成一个monkeytype.sqlite3
的文件. 之后我们在运行monkeytype stub some.module
可以打印出更改之后的样子. 例如在我们这个例子里我们应该运行下面的命令.
- monkeytype stub some.addFunction
当然我们也可以直接对原始的文件进行修改, 直接运行monkeytype apply some.module
即可. 例如在我们这个例子中, 我们应该运行下面的命令.
- monkeytype apply some.addFunction
他会自动对addFunction.py
文件进行直接的修改. 修改之后的内容为:
- class add_number(object):
- """这是一个加法运算
- """
- def __init__(self, a: int, b: int) -> None:
- self.a = a
- self.b = b
- def add_n(self) -> int:
- c = self.a + self.b
- return c
这样我们就增加了相应的变量的类型和返回值的类型.
出现UnicodeDecodeError的报错
如果在使用monkeytype apply some.module
的时候出现如下的报错,
UnicodeDecodeError: 'gbk' codec can't decode byte 0x9c in position 109: illegal multibyte sequence
这可能是因为我们在要修改的文件是使用utf-8进行编码的. 我们需要修改一下monkeytype
的源文件. 打开如下路径的文件:
- <PYTHON HOME>\python38\lib\site-packages\monkeytype\cli.py
找到函数apply_stub_handler
, 找到read_text
和write_text
, 在里面加上参数encoding="UTF-8"
. 完整的函数如下所示, 我们修改了第11和第14行.
- def apply_stub_handler(args: argparse.Namespace, stdout: IO, stderr: IO) -> None:
- stub = get_stub(args, stdout, stderr)
- if stub is None:
- complain_about_no_traces(args, stderr)
- return
- module = args.module_path[0]
- mod = importlib.import_module(module)
- source_path = Path(inspect.getfile(mod))
- source_with_types = apply_stub_using_libcst(
- stub=stub.render(),
- source=source_path.read_text(encoding="UTF-8"),
- overwrite_existing_annotations=args.existing_annotation_strategy == ExistingAnnotationStrategy.IGNORE,
- )
- source_path.write_text(source_with_types, encoding="UTF-8")
- print(source_with_types, file=stdout)
- 微信公众号
- 关注微信公众号
- QQ群
- 我们的QQ群号
评论