如何强制帮助使用覆盖 __doc__
How to force help to use overridden __doc__
假设我定义了一个简单的 class Foo
:
class Foo(object):
"""This is Foo"""
def __init__(self, label):
self.__doc__ = "This is {} Foo".format(label)
def __call(self, *args):
... # Some behavior which depends on the constructor arguments.
我看到对象 __doc__
被 ?
在 IPython 中拾取:
In [1]: %doctest_mode
Exception reporting mode: Plain
Doctest mode is: ON
>>> some = Foo("some")
>>> ?some
Type: Foo
String form: <__main__.Foo object at 0x7f01620a49b0>
Docstring: This is some Foo
Class docstring: This is Foo
但被 help
忽略:
>>> help(some)
Help on Foo in module __main__ object:
class Foo(builtins.object)
| This is Foo
|
| Methods defined here:
|
| __init__(self, label)
| Initialize self. See help(type(self)) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
(END)
是否可以在不修改 Class docstring
的情况下影响 help
行为?我希望 Class docstring
在处理实例时被忽略。
强制执行 help
函数需要根据我的理解更改其实现。创建一个临时在 class 上重新分配 __doc__
的小辅助函数要容易得多:
def my_help(obj):
if not isinstance(obj, type): # instances
old_doc, type(obj).__doc__ = type(obj).__doc__, obj.__doc__
help(type(obj))
type(obj).__doc__ = old_doc
else:
help(obj)
根据我的理解,这产生了用实例的文档字符串替换 class:
的预期效果
my_help(Foo('foo'))
Help on class Foo in module __main__:
class Foo(builtins.object)
| This is foo Foo
|
| Methods defined here:
|
| __init__(self, label)
| Initialize self. See help(type(self)) for accurate signature.
|
# .. snipped ..
不过,我不太喜欢这样,并且还知道您必须在其中对 class 执行 try-except
,因为它们不允许您像那样设置属性.简而言之,可行但笨拙。
首先:我不会推荐它!如果你根据参数认真地改变逻辑,你可能最好使用工厂函数和几个不同的 (sub-)类.
话说回来:这是可能的。一种方法是使用动态类型和子类化。但是你需要使用 __new__
而不是 __init__
:
class Foo(object):
"""This is Foo"""
def __new__(cls, label):
newcls = type('FooSubclass', (Foo, ), {'__doc__': "This is {} Foo".format(label)})
return newcls
>>> help(Foo('a'))
Help on class FooSubclass in module __main__:
class FooSubclass(Foo)
| This is a Foo
|
| Method resolution order:
| FooSubclass
| Foo
| __builtin__.object
|
| Static methods inherited from Foo:
|
| __new__(cls, label)
|
| ----------------------------------------------------------------------
| Data descriptors inherited from Foo:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
假设我定义了一个简单的 class Foo
:
class Foo(object):
"""This is Foo"""
def __init__(self, label):
self.__doc__ = "This is {} Foo".format(label)
def __call(self, *args):
... # Some behavior which depends on the constructor arguments.
我看到对象 __doc__
被 ?
在 IPython 中拾取:
In [1]: %doctest_mode
Exception reporting mode: Plain
Doctest mode is: ON
>>> some = Foo("some")
>>> ?some
Type: Foo
String form: <__main__.Foo object at 0x7f01620a49b0>
Docstring: This is some Foo
Class docstring: This is Foo
但被 help
忽略:
>>> help(some)
Help on Foo in module __main__ object:
class Foo(builtins.object)
| This is Foo
|
| Methods defined here:
|
| __init__(self, label)
| Initialize self. See help(type(self)) for accurate signature.
|
| ----------------------------------------------------------------------
| Data descriptors defined here:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)
(END)
是否可以在不修改 Class docstring
的情况下影响 help
行为?我希望 Class docstring
在处理实例时被忽略。
强制执行 help
函数需要根据我的理解更改其实现。创建一个临时在 class 上重新分配 __doc__
的小辅助函数要容易得多:
def my_help(obj):
if not isinstance(obj, type): # instances
old_doc, type(obj).__doc__ = type(obj).__doc__, obj.__doc__
help(type(obj))
type(obj).__doc__ = old_doc
else:
help(obj)
根据我的理解,这产生了用实例的文档字符串替换 class:
的预期效果my_help(Foo('foo'))
Help on class Foo in module __main__:
class Foo(builtins.object)
| This is foo Foo
|
| Methods defined here:
|
| __init__(self, label)
| Initialize self. See help(type(self)) for accurate signature.
|
# .. snipped ..
不过,我不太喜欢这样,并且还知道您必须在其中对 class 执行 try-except
,因为它们不允许您像那样设置属性.简而言之,可行但笨拙。
首先:我不会推荐它!如果你根据参数认真地改变逻辑,你可能最好使用工厂函数和几个不同的 (sub-)类.
话说回来:这是可能的。一种方法是使用动态类型和子类化。但是你需要使用 __new__
而不是 __init__
:
class Foo(object):
"""This is Foo"""
def __new__(cls, label):
newcls = type('FooSubclass', (Foo, ), {'__doc__': "This is {} Foo".format(label)})
return newcls
>>> help(Foo('a'))
Help on class FooSubclass in module __main__:
class FooSubclass(Foo)
| This is a Foo
|
| Method resolution order:
| FooSubclass
| Foo
| __builtin__.object
|
| Static methods inherited from Foo:
|
| __new__(cls, label)
|
| ----------------------------------------------------------------------
| Data descriptors inherited from Foo:
|
| __dict__
| dictionary for instance variables (if defined)
|
| __weakref__
| list of weak references to the object (if defined)