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

2018-08-16 11:37:30 +08:00
 Cheez

    @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 能只能提示而已啊,怎么这么难

3831 次点击
所在节点    Python
39 条回复
Cheez
2018-08-16 15:57:32 +08:00
@wzxlovesy #19 首先,你得给他们一个键盘.....
Trim21
2018-08-16 16:03:35 +08:00
感觉这不是你 type hint 写的有问题,是没能成功 import People

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

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

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


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

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

from __future__ import annotations
Cheez
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
2018-08-16 19:15:12 +08:00
@forrestchang #31 我终于发现问题了(暴风哭泣
是因为我不知道怎么返回一个返回自定义对象的迭代器........问题是我现在还是不知道.....
Trim21
2018-08-16 19:17:58 +08:00
@Cheez 你写的没错…
Cheez
2018-08-16 19:23:11 +08:00
@Trim21 #34 可是没有反应啊(暴风哭泣
Trim21
2018-08-16 19:26:34 +08:00
@Cheez 这就是编辑器的事了…
lynskylate
2018-08-16 19:28:40 +08:00
docstring 这个有很多种格式,大部分都能解析,比如一种格式是:rtype:类型,3.5 以上学学 type hint
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
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()]:
```


老实说,我完全不知道该怎么加了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/480325

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX