Python中如何让IDE识别实例方法返回指定类的类型?
@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 能只能提示而已啊,怎么这么难

Python中如何让IDE识别实例方法返回指定类的类型?
挽尊
from typing import TypeVar, Generic
T = TypeVar('T')
class Builder(Generic[T]):
def __init__(self):
self._instance = None
def build(self) -> T:
return self._instance
class MyClass:
def __init__(self):
self.value = 0
class MyClassBuilder(Builder[MyClass]):
def __init__(self):
super().__init__()
self._instance = MyClass()
def set_value(self, val: int) -> 'MyClassBuilder':
self._instance.value = val
return self
# 使用示例
builder = MyClassBuilder()
# IDE现在能识别返回的是MyClass实例
instance = builder.set_value(10).build() # instance被识别为MyClass类型
print(instance.value) # 输出: 10
核心是用泛型(Generic[T])和类型变量(TypeVar)来声明返回类型。这样IDE和类型检查器就能知道build()方法返回的是特定类型而不是通用的Builder。
简单说就是用泛型标注返回的具体类型。
IDE 推荐 Pycharm,你的第二个错误是模块名和类名冲突了。
#2 正常使用没事的
两次 from .People import People 是想怎样
#4 没别的办法,只能试一试。。。
可以试一下文档注释,看看 IDE 认不认识。
#6 怎么注释,求教
<br> .log_attr<br> .iter_factory('voters')<br> def voters(x)->'People':<br> '''获取答案的点赞列表''' <br> from .People import People<br> return People(x)<br>
在第一个 People 两边加了个引号,试试看……
#8 试过了…It don;t works
我试了下 pycharm 有没有 decorator 都是可以正常提示的,你试一下 docstring 吧
“”"
:return: People
“”"
另外你的代码没太懂,voters 是实例方法么,为啥没有 self 或者 staticmethod
。。。我怎么感觉,这两个异常,是非常基础的语法问题?
#12 你没感觉错,可是我想不到别的方法了
> It don;t works
呼唤 哥来给你指正这句话里出现了哪些错误(逃
#11 我把 voters 绑定到了一个数据源,这里的 voters 实际上只是处理数据的函数。
尴尬,关键时刻忘记 geelow 哥的 id 怎么写的了
#10 docstring 也没有用(暴风哭泣
#16
不会用英语就不要写……这语法错误小学三年级的孩子都不会犯
pycharm 可以使用 typehits 获得
#19 首先,你得给他们一个键盘…
感觉这不是你 type hint 写的有问题,是没能成功 import People
pycharm 的话,如果你写的是某个类的方法,想要返回方法所在的类,就像 8 楼一样加引号。如果是其他的函数的话直接像你原来那么写就可以,前提是你成功的把 People 给引入了。
#22 是的,问题就是 People 是这个类的子类。。。如果我在模块那边引入的话就会造成循环
class Zhihu(:
…class People:
…pass
这个类是这样的?
感谢提醒
if False:
from .people import People
https://stackoverflow.com/questions/39740632/python-type-hinting-without-cyclic-imports
#27 我放弃了…Sublime 太智能了,只能在这个 if 里面智能提示,出了 if 又啥都不认得了
#18 #16 阅,但所有人都知道了(还有标点错误😵
lz 先列一下 Python 的版本吧,看提示,应该是 import 的问题。
加引号是用在 using before definition 情况下的,但是在 3.7 中不需要了,只需:
from future import annotations
#30
#27
#20
我想错了…
https://pic1.zhimg.com/80/v2-918dc1f05d88c1212d3388fe347639d6_hd.png
其实是可以返回的,只不过我返回的是一个迭代器,而我却标注为 People 对象,所以识别不了。
那么问题来了,我试了一下<br>from typing import Iterator<br>...<br>...<br>def voters(x)->Iterator[People]:<br>
可是没有反应…
在 Google 搜了一圈,好像没有对复杂类型的迭代器该如何定义这个问题的相关…
#31 我终于发现问题了(暴风哭泣
是因为我不知道怎么返回一个返回自定义对象的迭代器…问题是我现在还是不知道…
#34 可是没有反应啊(暴风哭泣
这就是编辑器的事了…
docstring 这个有很多种格式,大部分都能解析,比如一种格式是:rtype:类型,3.5 以上学学 type hint
#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] 这样就可以了。
#38
我是这么做的<br>.log_attr #一个装饰器,根据 doc-string 输出日志<br> .iter_factory('voters') #一个装饰器,最终返回一个生成器<br> def voters(x): #对数据的处理<br> '''获取答案的点赞列表''' <br> from .People import People<br> return People(x)<br><br><br>def iter_factory(url_function_name, method=json):<br> """返回一个用 deal 遍历 obj 的生成器<br><br> Arguments:<br> action_name {[string]} -- [动作的名字]<br> deal_function {[function]} -- [处理遍历到的数据的函数]<br> method {[type]} -- [处理 URL 的函数] (default: {json})<br> method_arg {[type]} -- [剩下要传给 method 的参数]<br><br> Returns:<br> [iter] -- [生成器]<br> """<br> def decorate(deal_function): # 一个装饰器<br> import functools<br><br> def wrap(prop):<br> prop.__doc__ = deal_function.__doc__<br> return prop<br><br> def iter_function(count=-1, start=1, page=-1)->Iterable[People()]:<br>
老实说,我完全不知道该怎么加了

