在Python文档字符串中作为抽象类名称的参数的类型是什么?

时间:2018-12-28 09:38:45

标签: python class types docstring

已编辑:假设我有一些类是从SuperFoo抽象类继承的:

from abc import ABCMeta, abstractmethod

class SuperFoo(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def do_something():
        pass

class Foo(SuperFoo):
    def __init__(self):
        pass

    def do_something():
        pass

class Bar(SuperFoo):
    def __init__(self):
        pass

    def do_something():
        pass

还有一个文档化的函数,它以SuperFoo的子类作为参数:

def build(super_foo):
    """
    Instantiate a SuperFoo class and do some other stuff.
    @param super_foo: The subclass whose constructor will be called
    @type super_foo: ??? <--- What to use here?
    @return: An instance of a SuperFoo subclass
    @rtype: SuperFoo
    """
    # Do some stuff

    instance = class_name()  # Instantiate class
    return instance

foo = build(Foo)
bar = build(Bar)

在函数的文档字符串中应该使用什么@type?它不能为SuperFoo,因为它将对应于SuperFoo的实例,而不是类型本身。

2 个答案:

答案 0 :(得分:3)

motyzk已经发布了简单的技术答案-在您的示例中,您传递给build的是类,因此(名字不明确的)class_name参数的类型为{{1} }-的限制(基于您的代码段),此类不应包含任何参数,该参数不对应于任何明确定义的现有内置“类型”。

现在在Python中的注释中提到

  • 一切都是对象(以及类的实例)
  • 实例化类是通过调用类对象来完成的,就像调用任何函数一样,
  • 所有可调用对象都返回一个对象,即使是隐式的(type也是一个对象)

因此,您的None函数在技术上将与不需要参数的任何任何调用相同。例如:

build

从技术上讲是正确的。

现在您在函数的文档字符串中提及(强调是我的):

  

实例化一个类并做一些其他事情

由于您的功能将完全无效,如您所发布的代码片段所示,我假设在您的 real 代码中,重要的部分位于(未显示)“执行其他操作”中,而“其他操作”部分则依赖于所传递类的某些特定属性。

在这种情况下,您应该非正式地(在文档字符串本身中)或formally using the abc module中记录这些特性。这实际上不会解决您的问题-您的函数需要一个类,而不是实例,因此理论上@type应该是def bar(): return whatever = build(bar) ,但是得到的是type(YourABC)。此时,您要么必须编写一个自定义元类(从abc.ABCMeta继承),然后将其指定为正确的@type,但是就文档而言,这并没有说什么有用的信息,或者只是以文本形式描述它作为“ MyABC子类”(这是正确的描述,但不适用于代码检测)。

答案 1 :(得分:2)

运行时可以看到类型是“类型”:

class Foo(object):
    def __init__(self):
        pass


def f(t):
    print(type(t)) # <class 'type'>

f(Foo)