已编辑:假设我有一些类是从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
的实例,而不是类型本身。
答案 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)