代码补全没有提供推荐

16 投票
8 回答
20372 浏览
提问于 2025-04-17 16:45

假设我在使用Python的'requests'库。

req = requests.get("http://google.com")

现在在这之后,如果我输入req.,我应该能看到一个我可以使用的所有方法的列表。但是不知道为什么,我没有看到,即使我手动按Ctrl+Space也不行。

如果我在iPython里试这个,我能得到自动补全的建议。即使我在PyCharm的内置Python控制台里试,也能得到建议。

这到底是为什么呢?

8 个回答

1

PyCharm 这个工具如果你动态填充一个 dict(字典),它就不知道里面具体有什么内容。所以你需要提前告诉 PyCharm 这个 dict 的键是什么。Prodict 就是用来给 PyCharm 提示的,这样你就能享受到代码自动补全的功能。

首先,如果你想访问响应对象,你需要获取一个 json 格式的响应,并把它转换成 dict。这可以通过 requests 库的 .json() 方法来实现,像这样:

response = requests.get("https://some.restservice.com/user/1").json()

好了,我们把它加载到了一个 dict 对象中,现在你可以用方括号语法来访问里面的键:

print(response['name'])

既然你想要自动补全代码,那你肯定需要告诉 PyCharm 这个 dict 的键。如果你已经知道响应的结构,可以使用 Prodict 来给 PyCharm 提示:

class Response(Prodict):
    name: str
    price: float

response_dict = requests.get("https://some.restservice.com/user/1").json()

response = Response.from_dict(response_dict)
print(response.name)
print(response.price)

在上面的代码中,nameprice 这两个属性都能自动补全。

如果你不知道响应的结构,仍然可以用点语法来访问 dict 的属性,像这样:

response_dict = requests.get("https://some.restservice.com/user/1").json()
response = Prodict.from_dict(response_dict)
print(response.name)

但是代码补全就无法使用,因为 PyCharm 不知道结构是什么。

更重要的是,Prodict 类是直接从 dict 继承来的,所以你也可以把它当作 dict 来使用。

这是 Prodict 仓库中的一张截图,展示了代码补全的效果:

Prodict code completion

免责声明: 我是 Prodict 的作者。

8

Python是一种动态类型的编程语言,这意味着“get”这个函数在定义的时候并没有说明它会返回什么类型的结果。当你在IPython或者PyCharm的控制台输入代码时,实际上这些代码是被执行的,你可以在运行的解释器中查看对象的实例,并获取它的方法列表。而在PyCharm或者其他Python开发环境中输入代码时,代码并不会被执行,这时候只能通过静态分析来推测这个方法的返回类型,但并不是所有情况下都能做到这一点。

23

因为Python是一种动态类型的语言,所以你需要确保它能够正确识别各种数据的类型,并且能够检查你系统上库的类型。尽量让你的代码中对象的类型显而易见。

在PyCharm 2.7版本(那个时候版本号还是数字)中,有一个不错的方法是启用运行时类型检测——PyCharm在你调试程序时会插入到你的程序中,检查变量在使用时的类型。

你可以通过进入设置,找到“构建、执行、部署”部分,然后进入“Python调试器”子部分,启用“收集运行时类型信息以便代码提示”来开启这个功能。

PyCharm设置界面,显示相关设置。

当然需要注意的是,这个功能并不是完美的——如果你修改了代码,它不会在代码执行前更新,而且它只能告诉你它见过的值——你没有尝试过的其他代码路径可能会设置其他类型。

你还可以通过使用Epydoc或Sphinx风格的文档字符串来“告诉”PyCharm参数和返回值的类型信息。PyCharm会利用这些信息来改善它的检查。

从Python 3开始,Python也支持函数注解。这些可以用作类型提示,具体可以参考PEP 484。更多信息可以查看typing模块。这种方式更正式,因此也可以用于像mypy这样的工具,它是一个类型检查器,可以程序化地检查这些类型的一致性,从而为Python提供类似TypeScript的可选静态类型。

撰写回答