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
Cheez
V2EX  ›  Python

Python 里面如何让 IDE 知道实例方法会返回指定的类?

  •  
  •   Cheez · 2018-08-16 11:37:30 +08:00 · 3794 次点击
    这是一个创建于 2051 天前的主题,其中的信息可能已经有所发展或是发生改变。
    
        @zhihu.log_attr
        @zhihu.iter_factory('voters')
    	def voters(x)->People:
            '''获取答案的点赞列表''' 
            from .People import People
            return People(x)
    

    这样报错:NameError: name 'People' is not defined

        from .People import People
    
        @zhihu.log_attr
        @zhihu.iter_factory('voters')
        def voters(x)->People:
            '''获取{name}的点赞列表'''
            from .People import People
            return People(x)
    

    这样报错:ImportError: cannot import name 'People' from 'ZhihuVAPI.content.People'

    我只是想要 IDE 能只能提示而已啊,怎么这么难

    39 条回复    2018-08-16 23:50:43 +08:00
    Cheez
        1
    Cheez  
    OP
       2018-08-16 11:46:26 +08:00
    挽尊
    wrq
        2
    wrq  
       2018-08-16 11:55:59 +08:00 via iPhone
    IDE 推荐 Pycharm,你的第二个错误是模块名和类名冲突了。
    Cheez
        3
    Cheez  
    OP
       2018-08-16 12:01:20 +08:00
    @wrq #2 正常使用没事的
    xiexingjia
        4
    xiexingjia  
       2018-08-16 12:20:45 +08:00
    两次 from .People import People 是想怎样
    Cheez
        5
    Cheez  
    OP
       2018-08-16 12:21:22 +08:00
    @xiexingjia #4 没别的办法,只能试一试。。。
    NoDocCat
        6
    NoDocCat  
       2018-08-16 15:24:42 +08:00 via Android
    可以试一下文档注释,看看 IDE 认不认识。
    Cheez
        7
    Cheez  
    OP
       2018-08-16 15:26:00 +08:00
    @NoDocCat #6 怎么注释,求教
    panyanyany
        8
    panyanyany  
       2018-08-16 15:31:09 +08:00
    ```
    @zhihu.log_attr
    @zhihu.iter_factory('voters')
    def voters(x)->'People':
    '''获取答案的点赞列表'''
    from .People import People
    return People(x)
    ```

    在第一个 People 两边加了个引号,试试看……
    Cheez
        9
    Cheez  
    OP
       2018-08-16 15:36:22 +08:00
    @panyanyany #8 试过了......It don;t works
    virusdefender
        10
    virusdefender  
       2018-08-16 15:49:13 +08:00
    我试了下 pycharm 有没有 decorator 都是可以正常提示的,你试一下 docstring 吧

    """
    :return: People
    """
    virusdefender
        11
    virusdefender  
       2018-08-16 15:50:47 +08:00
    另外你的代码没太懂,voters 是实例方法么,为啥没有 self 或者 staticmethod
    zjb861107
        12
    zjb861107  
       2018-08-16 15:51:19 +08:00
    。。。我怎么感觉,这两个异常,是非常基础的语法问题?
    Cheez
        13
    Cheez  
    OP
       2018-08-16 15:52:00 +08:00
    @zjb861107 #12 你没感觉错,可是我想不到别的方法了
    laoyur
        14
    laoyur  
       2018-08-16 15:52:34 +08:00
    @Cheez
    > It don;t works
    呼唤 @geelow 哥来给你指正这句话里出现了哪些错误(逃
    Cheez
        15
    Cheez  
    OP
       2018-08-16 15:53:00 +08:00
    @virusdefender #11 我把 voters 绑定到了一个数据源,这里的 voters 实际上只是处理数据的函数。
    laoyur
        16
    laoyur  
       2018-08-16 15:54:41 +08:00
    @laoyur 尴尬,关键时刻忘记 geelow 哥的 id 怎么写的了
    Cheez
        17
    Cheez  
    OP
       2018-08-16 15:55:13 +08:00
    @virusdefender #10 docstring 也没有用(暴风哭泣
    Cheez
        18
    Cheez  
    OP
       2018-08-16 15:56:25 +08:00   ❤️ 1
    wzxlovesy
        19
    wzxlovesy  
       2018-08-16 15:56:25 +08:00 via Android
    @Cheez 不会用英语就不要写……这语法错误小学三年级的孩子都不会犯
    zhengxiaowai
        20
    zhengxiaowai  
       2018-08-16 15:57:08 +08:00
    pycharm 可以使用 typehits 获得
    Cheez
        21
    Cheez  
    OP
       2018-08-16 15:57:32 +08:00
    @wzxlovesy #19 首先,你得给他们一个键盘.....
    Trim21
        22
    Trim21  
       2018-08-16 16:03:35 +08:00 via Android
    感觉这不是你 type hint 写的有问题,是没能成功 import People

    pycharm 的话,如果你写的是某个类的方法,想要返回方法所在的类,就像 8 楼一样加引号。如果是其他的函数的话直接像你原来那么写就可以,前提是你成功的把 People 给引入了。
    Cheez
        23
    Cheez  
    OP
       2018-08-16 16:07:31 +08:00
    @Trim21 #22 是的,问题就是 People 是这个类的子类。。。如果我在模块那边引入的话就会造成循环
    Trim21
        24
    Trim21  
       2018-08-16 16:10:01 +08:00 via Android
    class Zhihu(:
    ....class People:
    ....pass

    这个类是这样的?
    laoyur
        25
    laoyur  
       2018-08-16 16:11:23 +08:00
    @Cheez 感谢提醒
    Cheez
        26
    Cheez  
    OP
       2018-08-16 16:12:05 +08:00
    @Trim21 #24

    People.py
    ```
    class People(content):
    pass
    ```


    Zhihu.py
    ```
    class content():
    pass
    ```
    Trim21
        27
    Trim21  
       2018-08-16 16:18:44 +08:00 via Android
    Cheez
        28
    Cheez  
    OP
       2018-08-16 16:30:29 +08:00
    @Trim21 #27 我放弃了.....Sublime 太智能了,只能在这个 if 里面智能提示,出了 if 又啥都不认得了
    geelaw
        29
    geelaw  
       2018-08-16 17:06:36 +08:00 via iPhone
    @Cheez #18 @laoyur #16 阅,但所有人都知道了(还有标点错误😵
    phithon
        30
    phithon  
       2018-08-16 18:39:12 +08:00
    forrestchang
        31
    forrestchang  
       2018-08-16 18:51:44 +08:00
    lz 先列一下 Python 的版本吧,看提示,应该是 import 的问题。

    @panyanyany 加引号是用在 using before definition 情况下的,但是在 3.7 中不需要了,只需:

    from __future__ import annotations
    Cheez
        32
    Cheez  
    OP
       2018-08-16 19:14:07 +08:00
    @phithon #30
    @Trim21 #27
    @zhengxiaowai #20

    我想错了...
    https://pic1.zhimg.com/80/v2-918dc1f05d88c1212d3388fe347639d6_hd.png

    其实是可以返回的,只不过我返回的是一个迭代器,而我却标注为 People 对象,所以识别不了。
    那么问题来了,我试了一下

    ```
    from typing import Iterator
    ...
    ...
    def voters(x)->Iterator[People]:
    ```
    可是没有反应...
    在 Google 搜了一圈,好像没有对复杂类型的迭代器该如何定义这个问题的相关...
    Cheez
        33
    Cheez  
    OP
       2018-08-16 19:15:12 +08:00
    @forrestchang #31 我终于发现问题了(暴风哭泣
    是因为我不知道怎么返回一个返回自定义对象的迭代器........问题是我现在还是不知道.....
    Trim21
        34
    Trim21  
       2018-08-16 19:17:58 +08:00 via Android
    @Cheez 你写的没错…
    Cheez
        35
    Cheez  
    OP
       2018-08-16 19:23:11 +08:00
    @Trim21 #34 可是没有反应啊(暴风哭泣
    Trim21
        36
    Trim21  
       2018-08-16 19:26:34 +08:00 via Android
    @Cheez 这就是编辑器的事了…
    lynskylate
        37
    lynskylate  
       2018-08-16 19:28:40 +08:00 via Android
    docstring 这个有很多种格式,大部分都能解析,比如一种格式是:rtype:类型,3.5 以上学学 type hint
    forrestchang
        38
    forrestchang  
       2018-08-16 23:25:02 +08:00
    @Cheez #33 你返回的是生成 People 对象的迭代器还是生成器?内置的迭代器类型有 List,不能用吗?还是 People 这个对象本身实现了迭代器协议?

    如果是使用 mypy 的话,建议参考:
    - https://mypy.readthedocs.io/en/latest/protocols.html:这个写了如何自定义协议,要使用 typing_extension 这个包
    - https://www.python.org/dev/peps/pep-0484/#the-type-of-class-objects:这个是和 class 相关如何做 type hints,要使用 Type[C]

    我看你的描述,获取点赞的列表,应该用 def x() -> List[People] 这样就可以了。
    Cheez
        39
    Cheez  
    OP
       2018-08-16 23:50:43 +08:00
    @forrestchang #38
    我是这么做的
    ```
    @zhihu.log_attr #一个装饰器,根据 doc-string 输出日志
    @zhihu.iter_factory('voters') #一个装饰器,最终返回一个生成器
    def voters(x): #对数据的处理
    '''获取答案的点赞列表'''
    from .People import People
    return People(x)


    def iter_factory(url_function_name, method=json):
    """返回一个用 deal 遍历 obj 的生成器

    Arguments:
    action_name {[string]} -- [动作的名字]
    deal_function {[function]} -- [处理遍历到的数据的函数]
    method {[type]} -- [处理 URL 的函数] (default: {json})
    method_arg {[type]} -- [剩下要传给 method 的参数]

    Returns:
    [iter] -- [生成器]
    """
    def decorate(deal_function): # 一个装饰器
    import functools

    def wrap(prop):
    prop.__doc__ = deal_function.__doc__
    return prop

    def iter_function(count=-1, start=1, page=-1)->Iterable[People()]:
    ```


    老实说,我完全不知道该怎么加了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3310 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 42ms · UTC 13:31 · PVG 21:31 · LAX 06:31 · JFK 09:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.