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识别实例方法返回指定类的类型?

39 回复

挽尊


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)-&gt;'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

这个类是这样的?

感谢提醒

#24

People.py
<br>class People(content):<br> pass<br>


Zhihu.py
<br>class content():<br> pass<br>

#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)-&gt;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)-&gt;Iterable[People()]:<br>


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

回到顶部