Python docstring类型注释-一个类,而不是一个实例?

问题描述 投票:8回答:5

假设我有:

class A(object):
   pass

class B(A):
   pass

我想声明一个将A的子类作为参数的函数:

def do_something(klass):
   """
   :type klass: WHAT_HERE
   """
   pass

我应该在WHAT_HERE中输入什么?如果我这样做:

:type klass: A

PyCharm认为我应该给A的实例作为参数,而不是类本身。

python pycharm
5个回答
4
投票

根据pycharm docs尽可能接近的是:

() -> SomeClass

因此在您的示例中

def do_something(klass):
   """
   :type klass: () -> A
   """
   pass

(对于PyCharm而言,这意味着您提供的参数是一个返回给定类型的对象的函数。创建对象后,它将正确键入提示任何内容。


2
投票

[Guido回答了这个问题here,但是我认为PyCharm无法正确支持Python 2中的适当语法。我相信在PyCharm中,Python 2中的语法应该为(...) -> A。在Python 3中,适当的语法为Callable[..., A] ]。

[我注意到PyCharm也不将() -> A视为一类;如果您使用此语法在A上调用类方法,则PyCharm检查将标记为找不到引用的类方法。

虽然是filed in the JetBrains bugtracker,但已根据先前的评论关闭。鉴于Guido在第一个参考文献中的最新评论,我希望JetBrains将重新打开。


2
投票

答案为Type。如果安装了typing模块,则也可以将此类绑定为某些内容的子类,如以下示例所示:

class BaseUser(): pass        
class Admin(BaseUser): pass
class Staff(BaseUser): pass
class Client(BaseUser): pass

然后

from typing import Type, TypeVar

U = TypeVar('U', bound=BaseUser)

def new_user(user_class):
    """
    type user_class: Type[U]
    """
    return user_class()

及以下是用法

new_user(Admin)
new_user(Client)
new_user(Staff)

Pycharm | IDEA理解typing的提示非常好,因此可以解决问题


0
投票

所有类都是type类的实例:

>>> class Foo:
...     pass
... 
>>> type(Foo())
<class '__main__.Foo'>
>>> type(Foo)
<class 'type'>
>>> type(Foo) is type
True

因此,有效答案将是:

:type klass: type

0
投票

[无法在PyCharm或IDEA中使用Python 2的docstring语法来做到这一点。

但是,您可以通过在用法上方放置assert语句来获得变量的代码完成:

def call_foo(cls):
  """
  Calls the class method ``foo`` of the given class.

  :param cls: a subclass of SomeClass
  :type cls: type
  """
  assert issubclass(cls, SomeClass)
  cls.foo()  # you'll get code completion here for the foo method defined in SomeClass
© www.soinside.com 2019 - 2024. All rights reserved.