【问题标题】:How to specify class or function type in docstring for PyCharm parser如何在 PyCharm 解析器的文档字符串中指定类或函数类型
【发布时间】:2015-07-10 13:45:34
【问题描述】:

我经常使用 Pycharm 文档字符串类型解析器来指定方法参数和返回的类型、属性或实例变量。如果它几乎一直都有效,我有一点关于告诉 PyCharm 我将函数或类作为参数/属性/...

这是一个简短的例子:

class Bar:

    def __init__(self, bar):
        """
        :type bar: str
        """
        print bar

class Foo:
    """
    :type my_class: Bar.__class__
    """

    def __init__(self, cinstance=Bar):
        """
        :type cinstance: Bar.__class__
        """
        self.my_class = cinstance

    def run(self):
        # it should print an unexpected type warning, but it doesn't.
        self.my_class(2)

如果我只输入Bar 而不是Bar.__class__,PyCharm 会告诉我不能调用Bar。那么如何告诉他我正在给他上课呢?

请注意,使用 @classmethod 装饰器,PyCharm 可以毫无问题地理解我们谈论的是类而不是实例。

这是我的尝试:

【问题讨论】:

标签: python python-2.7 pycharm


【解决方案1】:

PyCharm 支持告诉我以下内容:

正如 PyCharm 开发人员所说:您无法在类型提示中区分类和实例。类型提示中的类名意味着需要该类的实例。如果您的函数接受类本身,则您的选择是根本不使用类型提示或使用“类型”作为类名。无论如何,在这些情况下不会有任何有用的代码完成。另见https://youtrack.jetbrains.com/issue/PY-11615

指定参数的唯一方法是使用类是使用:type arg: type,但完成不会很好。目前没有其他办法。

【讨论】:

  • 在这种情况下,我通常使用带有参数:type arg: type[SomeClass] 的类型。它也不提供语法帮助,但它是有效的类型提示语法,并且比 type 更具体。
  • @warownia1 似乎:type arg: type[SomeClass] 的类型提示在 PyCharm 2017.3.4 中正常工作。您可以将此作为答案发布吗?
  • 您可以通过在该变量的第一次使用上方插入assert issubclass(cls, SomeClass) 语句来获得该变量的代码完成
【解决方案2】:

如果你想指定一个参数的类型是SomeClass,它应该这样声明:

@type (param): SomeClass

如果指定正确,你应该会得到这样的结果:

如果您没有正确指定参数的类型:

在这一点上,我想我会更深入地挖掘一下,看看我是否能找到任何有趣的东西。如果你去声明一个对象的.__class__,你会被引导到这里(builtins.py):

也许__class__ 被设置为None?即使它是默认的,但在类被实例化时会更新(这将是我对会发生什么的猜测),这也可能是 PyCharm 推断的 __class__ 解析到的。所有这些都只是我的猜测,也可能是不正确的,但是......只是为了它,如果我们将参数的类型设置为None,我们会看到什么行为呢?

看起来与我们将类型设置为 SomeClass.__fake__ 时发生的事情相同(我用SomeClass.__class__ 对其进行了测试,那里也发生了同样的事情。)

所以我想现在的问题是,你为什么不能使用@type cinstance: Bar

【讨论】:

  • 仅供参考,感谢 this answer PyCharm 支持的文档样式
  • 我阅读了您的答案,但我不确定您是否遇到问题:我正在寻找一种将类作为属性而不是实例作为属性传递的方法。我知道例如,@param toto: Bar 没问题,但是如何告诉“我希望非实例化类等于或继承自 Bar 作为参数”?
  • @FunkySayu 我明白了。你试过.__name__ 还是只是class?另外,如果你碰巧让class 工作,我不确定它会做你想做的事情,因为class 对象不会知道它实际解析到哪个类(对吗?)
  • (我添加了一些屏幕截图以便更好地解释)。我也尝试了名称,但它仍然无法正常工作。关于你问的第二个问题(这很有趣),我的逻辑是如果你有一个继承的 Bar 类,它通常会覆盖或让 Bar 的方法定义。但正如您所说,__class__ 看起来 not 为旧式类定义,而被定义为 type 用于新式类。我不确定有没有办法做到这一点。
  • 酷。抱歉,我无法正确回答您的问题,但为您如此透彻而欢呼!
【解决方案3】:

对于函数,使用 callable 指定适用于 PyCharm。

【讨论】:

    【解决方案4】:

    试试这个:

    from typing import Type
    
    def __init__(self, klass: Type[Bar]):
        pass
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-29
      • 2016-05-14
      相关资源
      最近更新 更多