简体   繁体   English

如何在 PyCharm 解析器的文档字符串中指定类或函数类型

[英]How to specify class or function type in docstring for PyCharm parser

I use a lot the Pycharm docstring type parser in order to specify the types of the methods parameters and return, the attributes or the instance variable.我经常使用 Pycharm 文档字符串类型解析器来指定方法参数和返回的类型、属性或实例变量。 If it works nearly all the time, I have a little issue about telling PyCharm I am giving a function or a class as parameter/attribute/...如果它几乎一直工作,我有一个小问题告诉 PyCharm 我给一个函数或一个类作为参数/属性/...

Here is a short example :这是一个简短的例子:

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)

If I just put Bar instead of Bar.__class__ , of course PyCharm tell me that Bar cannot be call.如果我只是把Bar而不是Bar.__class__ ,当然 PyCharm 告诉我Bar不能被调用。 So how to tell him that I'm giving him the class ?那么如何告诉他我正在给他上课呢?

Note that with the @classmethod decorator, PyCharm has no issue to understand we are speaking about the class and not the instance.请注意,使用@classmethod装饰器,PyCharm 可以@classmethod理解我们谈论的是类而不是实例。

Here are my attempts :这是我的尝试:

尝试使用 <code>Bar.__name__</code>

尝试使用 <code>Bar.__class__</code>

尝试使用 <code>Bar</code>

The PyCharm support told me the following : PyCharm 支持告诉我以下内容:

As PyCharm developer said: You cannot distinguish classes and instances in type hints.正如 PyCharm 开发人员所说:您无法在类型提示中区分类和实例。 The name of a class in a type hint means that an instance of that class is expected.类型提示中的类名称意味着需要该类的实例。 If your function accepts the class itself, your options are either not to use type hints at all or use the 'type' as a class name.如果您的函数接受类本身,您的选择要么根本不使用类型提示,要么使用“类型”作为类名。 Anyway, there won't be any useful code completion in these cases.无论如何,在这些情况下不会有任何有用的代码完成。 See also https://youtrack.jetbrains.com/issue/PY-11615 .另请参阅https://youtrack.jetbrains.com/issue/PY-11615

The only way to specificate an argument is a class is to use :type arg: type , but the completion won't work well.指定参数是一个类的唯一方法是使用:type arg: type ,但完成不会很好地工作。 There is no other way currently.目前没有其他办法。

If you want to specify that a parameter is of type SomeClass , it should be declared as such:如果要指定参数的类型为SomeClass ,则应将其声明为:

@type (param): SomeClass

Specified properly, you should get something like this:正确指定,你应该得到这样的东西:

第1部分

If you don't specify the type of the parameter properly:如果没有正确指定参数的类型:

第2部分

At this point, I figured I would dig a little deeper to see if I could find anything interesting.在这一点上,我想我会深入挖掘一下,看看是否能找到任何有趣的东西。 If you go to the declaration of an object's .__class__ , you'll be directed here (in builtins.py ):如果你去声明一个对象的.__class__ ,你会被引导到这里(在builtins.py ):

第 3 部分

Perhaps __class__ was set to None ?也许__class__被设置为None Even if it is by default but then updated when the class gets instantiated (which would be my guess as to what happens), this might be what PyCharm infers __class__ resolves to.即使它是默认的,但在类被实例化时更新(我猜测会发生什么),这可能是 PyCharm 推断__class__解析的内容。 All of this is just speculation on my end and may as well be incorrect, but... Just for the heck of it, what behavior can we see if we set a parameter's type to None , then?所有这一切都只是我的推测,也可能是不正确的,但是......只是为了它,如果我们将参数的类型设置为None ,我们会看到什么行为?

第 4 部分

Looks like the same thing that happened when we set the type to SomeClass.__fake__ (and I tested it with SomeClass.__class__ , and the same thing happens there too.)看起来与我们将类型设置为SomeClass.__fake__时发生的事情相同(我使用SomeClass.__class__对其进行了测试,同样的事情也发生在那里。)

So I suppose the question at hand is, why can't you use @type cinstance: Bar ?所以我想手头的问题是,你为什么不能使用@type cinstance: Bar

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

Try this:尝试这个:

from typing import Type

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM