Python docstring 类型注释 -- class,不是实例?
Python docstring type annotation -- a class, not an instance?
假设我有:
class A(object):
pass
class B(A):
pass
我想声明一个以 A 的子class 作为参数的函数:
def do_something(klass):
"""
:type klass: WHAT_HERE
"""
pass
我应该在 WHAT_HERE 中输入什么?如果我这样做:
:type klass: A
PyCharm 认为我应该给出 A 的实例作为参数,而不是 class 本身。
所有 class 都是 type
class:
的实例
>>> class Foo:
... pass
...
>>> type(Foo())
<class '__main__.Foo'>
>>> type(Foo)
<class 'type'>
>>> type(Foo) is type
True
所以,一个有效的答案是:
:type klass: type
根据 pycharm docs 可以得到的最接近的是:
() -> SomeClass
所以在你的例子中
def do_something(klass):
"""
:type klass: () -> A
"""
pass
这意味着(对于 PyCharm)您提供的参数是一个函数,returns 一个给定类型的对象。它会在对象创建后正确键入任何提示。
Guido 回答了这个问题 here,但我认为 PyCharm 没有正确支持 Python 中的适当语法 2. 我认为语法应该是 (...) -> A
PyCharm 和 Python 2. 在 Python 3 中,适当的语法是 Callable[..., A]
.
我注意到 PyCharm 也不将 () -> A
视为 class;如果您使用此语法在 A 上调用 class 方法,PyCharm 检查将标记它找不到引用的 class 方法。
这已经 filed in the JetBrains bugtracker,但根据之前的评论已关闭。鉴于 Guido 最近在第一篇参考文献中发表的评论,我希望 JetBrains 能够重新开放。
答案是Type
。如果您安装了 typing
模块,您还可以将此 class 绑定为某个对象的子 class,如下例所示:
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
提示很好,所以它会成功
在 PyCharm 或 IDEA 中使用 Python 2 的文档字符串语法无法做到这一点。
但是,您可以通过在用法上方放置 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
假设我有:
class A(object):
pass
class B(A):
pass
我想声明一个以 A 的子class 作为参数的函数:
def do_something(klass):
"""
:type klass: WHAT_HERE
"""
pass
我应该在 WHAT_HERE 中输入什么?如果我这样做:
:type klass: A
PyCharm 认为我应该给出 A 的实例作为参数,而不是 class 本身。
所有 class 都是 type
class:
>>> class Foo:
... pass
...
>>> type(Foo())
<class '__main__.Foo'>
>>> type(Foo)
<class 'type'>
>>> type(Foo) is type
True
所以,一个有效的答案是:
:type klass: type
根据 pycharm docs 可以得到的最接近的是:
() -> SomeClass
所以在你的例子中
def do_something(klass):
"""
:type klass: () -> A
"""
pass
这意味着(对于 PyCharm)您提供的参数是一个函数,returns 一个给定类型的对象。它会在对象创建后正确键入任何提示。
Guido 回答了这个问题 here,但我认为 PyCharm 没有正确支持 Python 中的适当语法 2. 我认为语法应该是 (...) -> A
PyCharm 和 Python 2. 在 Python 3 中,适当的语法是 Callable[..., A]
.
我注意到 PyCharm 也不将 () -> A
视为 class;如果您使用此语法在 A 上调用 class 方法,PyCharm 检查将标记它找不到引用的 class 方法。
这已经 filed in the JetBrains bugtracker,但根据之前的评论已关闭。鉴于 Guido 最近在第一篇参考文献中发表的评论,我希望 JetBrains 能够重新开放。
答案是Type
。如果您安装了 typing
模块,您还可以将此 class 绑定为某个对象的子 class,如下例所示:
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
提示很好,所以它会成功
在 PyCharm 或 IDEA 中使用 Python 2 的文档字符串语法无法做到这一点。
但是,您可以通过在用法上方放置 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