V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
szzhiyang
V2EX  ›  Python

大家是如何实时检查 Python 变量类型的?

  •  
  •   szzhiyang · 2019-09-20 17:17:01 +08:00 · 5301 次点击
    这是一个创建于 1898 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我目前使用的 Python 实时类型检查方案是在 Microsoft Python Extension for VS Code 中启用 mypy --strict 检查,但是发现这个方案存在一些瑕疵,比如将鼠标悬停在某个变量名上方时 VS Code 不能详细提示它的类型(它只会把 Dict[str, int] 类型提示为 dict 类型)。

    我还尝试过 PyCharm ,不过不知道是因为 PyCharm 本身做不到还是我没找对门路,我一直没能将它设置为实时使用 mypy 检查。

    我现在想知道:

    • 大家是如何实时检查 Python 变量类型的?

    • Python 的类型检查体验真的没法达到 C++、C#、TypeScript 那样的程度吗?




    回复前必读:

    • 我想要的是 边写边检查,而不是在执行代码前才检查
    • 我了解 Python 的 Type Hints 语法( PEP 484 和 PEP 526 )
    • 不要回复“我不做类型检查”或者“没必要做类型检查”的言论

    第 1 条附言  ·  2019-09-21 17:58:49 +08:00

    如果你不理解为何要做类型检查,请观看该视频:

    Carl Meyer - Type-checked Python in the real world - PyCon 2018


    44 条回复    2019-09-28 09:21:24 +08:00
    expkzb
        1
    expkzb  
       2019-09-20 17:27:01 +08:00   ❤️ 1
    变量名加类型后缀😂
    szzhiyang
        2
    szzhiyang  
    OP
       2019-09-20 17:27:58 +08:00
    我承诺向认真回帖的热心 V 友发送感谢!
    star00
        3
    star00  
       2019-09-20 17:29:12 +08:00
    换语言
    shintendo
        4
    shintendo  
       2019-09-20 17:30:06 +08:00   ❤️ 1
    匈牙利命名法!
    szzhiyang
        5
    szzhiyang  
    OP
       2019-09-20 17:31:28 +08:00
    @expkzb 我知道这个语法,我在帖子中说了。😂
    szzhiyang
        6
    szzhiyang  
    OP
       2019-09-20 17:33:03 +08:00
    @shintendo 那该怎么命名类型为 Dict[str, Set[int]] 的变量呢?😂
    ClericPy
        7
    ClericPy  
       2019-09-20 17:36:34 +08:00   ❤️ 1
    Pydantic for the data parts.

    fastapi 里看到这个, 感觉还行, vscode 里开个 mypy 凑合用
    szzhiyang
        8
    szzhiyang  
    OP
       2019-09-20 17:39:50 +08:00
    @ClericPy 多谢,不过这个并不是我想要的那种,我想要的是一套 Linting 工具链。
    janxin
        9
    janxin  
       2019-09-20 17:42:14 +08:00
    这个看起来只是插件的问题,不过我试了一下我的插件的提示是正常的?
    ClericPy
        10
    ClericPy  
       2019-09-20 17:43:51 +08:00
    @szzhiyang 知道啊... 但是靠谱的试过都一般般啊, 之前最顺手是 pyright, 后来还是改回 mypy 了
    szzhiyang
        11
    szzhiyang  
    OP
       2019-09-20 17:44:25 +08:00
    @janxin 请问你用的是什么编辑器的什么插件?它能提示 Dict[str, Set[int]] 这种复杂的类型吗?
    szzhiyang
        12
    szzhiyang  
    OP
       2019-09-20 17:46:21 +08:00
    @ClericPy 谢谢你,我也试过 Pyright,不过它最严格的 Linting 规则达不到我的要求。😂
    iyaozhen
        13
    iyaozhen  
       2019-09-20 17:46:56 +08:00 via Android
    对楼主需求场景不太了解。

    日常开发中也有类型检查的需求,不过仅仅是方便对象方法提示,一般是通过注释显式表明类型。因为 pycharm 的类型推导确实不太准
    SbloodyS
        14
    SbloodyS  
       2019-09-20 17:50:05 +08:00
    我用 typing....
    ClericPy
        15
    ClericPy  
       2019-09-20 17:51:23 +08:00
    @szzhiyang 哈哈... 你能试的都试过了, 所以最好去 Reddit 上问... Pydantic 解决的是在 linter 里友好的显示类型, 你要的反而是个 linter... Pycharm 已经够高级了, 要啥自行车
    pakro888
        16
    pakro888  
       2019-09-20 18:16:14 +08:00 via Android
    使用 pycharm 按住 ctrl 同时指针悬浮到变量上可以提示吧。
    janxin
        17
    janxin  
       2019-09-20 18:29:53 +08:00
    跟你一样的插件,启用了 LSP。不过我只是看了一下同文件的,不同文件的没试过,理论上应该也差不多
    szzhiyang
        18
    szzhiyang  
    OP
       2019-09-20 18:33:52 +08:00
    @janxin LSP 是啥?
    szzhiyang
        19
    szzhiyang  
    OP
       2019-09-20 18:37:06 +08:00
    @ClericPy

    很多非常明显的类型错误 PyCharm 都查不出来,比如下列代码:

    test_str: str = "Hello World"
    test_int: int = 123456
    test_str += test_int

    是因为我没设置好 PyCharm 吗?😂
    clino
        20
    clino  
       2019-09-20 18:44:48 +08:00 via Android
    检查当然用 isinstance 啦 😄
    szzhiyang
        21
    szzhiyang  
    OP
       2019-09-20 21:42:34 +08:00
    @clino 你理解错我的意思了。😂
    LokiSharp
        22
    LokiSharp  
       2019-09-20 21:44:37 +08:00
    @szzhiyang #19 要用 mypy
    lance6716
        23
    lance6716  
       2019-09-20 21:59:53 +08:00 via Android
    这种 pyobject 强行检查类型又有多大用途呢…不如理清楚写码思路
    szzhiyang
        24
    szzhiyang  
    OP
       2019-09-20 22:07:26 +08:00
    @lance6716 这么做的好处会随着项目规模的增长变得越发明显。
    lance6716
        25
    lance6716  
       2019-09-20 22:09:33 +08:00 via Android
    @szzhiyang 那就不如换静态类型语言算了
    szzhiyang
        26
    szzhiyang  
    OP
       2019-09-20 22:11:02 +08:00
    @lance6716 要是能换,我就不会发这个帖子了。
    ClericPy
        27
    ClericPy  
       2019-09-20 22:18:40 +08:00
    @szzhiyang 不知道了, Pycharm 尝试过 5 次迁移都放弃了... 现在常驻 vscode 的...


    szzhiyang
        28
    szzhiyang  
    OP
       2019-09-20 22:29:34 +08:00
    @ClericPy 之前我一直以为用 PyCharm 写 Python 的体验就像用 Visual Studio 写 C# 那样,后来亲自尝试 PyCharm 后才发现我太天真了。😂
    szzhiyang
        29
    szzhiyang  
    OP
       2019-09-20 22:35:41 +08:00
    @pakro888 但是没有 mypy 加成的 PyCharm 对变量类型的检查能力非常羸弱。
    ClericPy
        30
    ClericPy  
       2019-09-20 22:38:59 +08:00
    @szzhiyang 我用过 Pycharm, 比你说的强太多了... 肯定也有插件什么的吧, 那么复杂一东西, 内存比 vscode 还少... 挺厉害了, 还是不会用
    yegle
        31
    yegle  
       2019-09-21 03:53:46 +08:00
    Python 的类型检查当然是垃圾啊。你来写一个类型注解,参数类型支持 iterable of strings 但是 exclude str type。
    ila
        32
    ila  
       2019-09-21 08:05:36 +08:00 via Android
    @expkzb 手动滑稽,me too
    a719114136
        33
    a719114136  
       2019-09-21 11:26:19 +08:00
    为啥要检查,又不能带来性能提升。 至于减少 bug,我写 py 这么久还真没见过因为这个造成的 bug (这种类型的 bug 在早期测试的时候完全能发现)。
    最多也就是函数的参数,返回值用 Type Hints 给个类型提示,函数里面那想咋用就咋用呗
    szzhiyang
        34
    szzhiyang  
    OP
       2019-09-21 12:59:45 +08:00 via iPhone
    @a719114136 类型检查还是很有必要的,不然 TypeScript 就不会问世了。
    szzhiyang
        35
    szzhiyang  
    OP
       2019-09-21 13:04:12 +08:00
    @ila 如果变量的数据类型比较复杂的话,比如 Dict[str, Set[int]],那就很难起变量名了。
    billlee
        36
    billlee  
       2019-09-21 15:23:15 +08:00
    弃坑上车 java
    bakabie
        37
    bakabie  
       2019-09-21 22:50:55 +08:00
    弃坑上 Go (
    sazima
        38
    sazima  
       2019-09-22 07:53:45 +08:00
    目前我也有点迷, 一般都是这么写
    user: User = session.query(User).first()
    users: Sequence[User] = session.query(User).all()

    def get_user_by_id(use_id: int) -> User:
    ....
    laike9m
        39
    laike9m  
       2019-09-22 10:26:32 +08:00   ❤️ 1
    试试 Google 的 pytype 呢?
    laike9m
        40
    laike9m  
       2019-09-22 10:45:57 +08:00
    @yegle 的确是个问题。没有 char 就算了这个不好改,但是我觉得 typing 应该加入 exclude types 支持。
    laike9m
        41
    laike9m  
       2019-09-22 11:04:01 +08:00
    @yegle 我又想了一下,根源不是不支持 exclude,而是不支持 AND 条件。但是 typing 支持 Union,所以按照现在的设计应该写成 Union[List[str], Tuple[str], Set[str]]。从某种意义上说这样更明确。
    szzhiyang
        42
    szzhiyang  
    OP
       2019-09-22 12:12:05 +08:00
    @laike9m 多谢,不过 pytype 好像不能被配置成实时检查的效果。
    yegle
        43
    yegle  
       2019-09-28 03:28:07 +08:00
    @laike9m 确实需要 exclude,或者正式支持 typing.Char

    举个例子,你给的 Union 类型并不支持 typing.Iterable,不支持 typing.KeysView/typing.ItemsView/typing.ValuesView


    这个是我几年前提的 FR:github.com/python/typing/issues/510
    laike9m
        44
    laike9m  
       2019-09-28 09:21:24 +08:00
    @yegle 是的。我的意思其实就是 typing 现在的思路是白名单。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2644 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 11:30 · PVG 19:30 · LAX 03:30 · JFK 06:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.