Python docstring type annotation — a class, not an instance?

前端 未结 5 1114
闹比i
闹比i 2021-01-18 01:23

Let\'s say I have:

class A(object):
   pass

class B(A):
   pass

I want to declare a function that takes a subclass of A as an argument:

相关标签:
5条回答
  • 2021-01-18 01:32

    All classes are an instance of the type class:

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

    So, a valid answer would be:

    :type klass: type
    
    0 讨论(0)
  • 2021-01-18 01:39

    The answer is Type. If you have a typing module installed, you can also bound this class to be a subclass of something, like in following example:

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

    then

    from typing import Type, TypeVar
    
    U = TypeVar('U', bound=BaseUser)
    
    def new_user(user_class):
        """
        type user_class: Type[U]
        """
        return user_class()
    

    and following are the usage

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

    Pycharm | IDEA understand typing hints quite good, so it will do the trick

    0 讨论(0)
  • 2021-01-18 01:46

    According to the pycharm docs as close as you can get is:

    () -> SomeClass
    

    So in your example

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

    This means (for PyCharm) that the argument you are providing is a function that returns an object of a given type. It will properly type hint anything after the object creation.

    0 讨论(0)
  • 2021-01-18 01:48

    There is no way to do this using the docstring syntax for Python 2 in PyCharm or IDEA.

    However, you can get code completion for the variable by placing an assert statement above the usage:

    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
    
    0 讨论(0)
  • 2021-01-18 01:49

    Guido answered this question here, but I believe PyCharm does not correctly support the appropriate syntax in Python 2. I believe the syntax should be (...) -> A in PyCharm with Python 2. In Python 3, the appropriate syntax is Callable[..., A].

    I note that PyCharm doesn't treat () -> A as a class either; if you call a classmethod on A using this syntax, PyCharm inspection will flag that it can't find the referenced classmethod.

    This has been filed in the JetBrains bugtracker, though was closed based on earlier comments. Given Guido's recent comments in the first reference, I'm hoping JetBrains will reopen.

    0 讨论(0)
提交回复
热议问题