我想在Python中做一些類繼承。我希望每個類和繼承的類都有良好的文檔。所以我覺得對於繼承類,我想它想:繼承Python類繼承docstrings
- 繼承基類的文檔字符串
- 可能追加額外的相關文檔,文檔字符串
是否有任何(可能或優雅pythonic)在類繼承情況下做這種類型的文檔字符串操作的方式?如何多重繼承?
我想在Python中做一些類繼承。我希望每個類和繼承的類都有良好的文檔。所以我覺得對於繼承類,我想它想:繼承Python類繼承docstrings
是否有任何(可能或優雅pythonic)在類繼承情況下做這種類型的文檔字符串操作的方式?如何多重繼承?
你不是唯一的!前段時間有關於comp.lang.python
的討論,並創建了一個配方。檢查出來here。
"""
doc_inherit decorator
Usage:
class Foo(object):
def foo(self):
"Frobber"
pass
class Bar(Foo):
@doc_inherit
def foo(self):
pass
Now, Bar.foo.__doc__ == Bar().foo.__doc__ == Foo.foo.__doc__ == "Frobber"
"""
from functools import wraps
class DocInherit(object):
"""
Docstring inheriting method descriptor
The class itself is also used as a decorator
"""
def __init__(self, mthd):
self.mthd = mthd
self.name = mthd.__name__
def __get__(self, obj, cls):
if obj:
return self.get_with_inst(obj, cls)
else:
return self.get_no_inst(cls)
def get_with_inst(self, obj, cls):
overridden = getattr(super(cls, obj), self.name, None)
@wraps(self.mthd, assigned=('__name__','__module__'))
def f(*args, **kwargs):
return self.mthd(obj, *args, **kwargs)
return self.use_parent_doc(f, overridden)
def get_no_inst(self, cls):
for parent in cls.__mro__[1:]:
overridden = getattr(parent, self.name, None)
if overridden: break
@wraps(self.mthd, assigned=('__name__','__module__'))
def f(*args, **kwargs):
return self.mthd(*args, **kwargs)
return self.use_parent_doc(f, overridden)
def use_parent_doc(self, func, source):
if source is None:
raise NameError, ("Can't find '%s' in parents"%self.name)
func.__doc__ = source.__doc__
return func
doc_inherit = DocInherit
您可以輕鬆地串連文檔字符串:
class Foo(object):
"""
Foo Class.
This class foos around.
"""
pass
class Bar(Foo):
"""
Bar class, children of Foo
Use this when you want to Bar around.
parent:
"""
__doc__ += Foo.__doc__
pass
然而,這是沒用的。大多數文檔生成工具(包括Sphinx和Epydoc)將已經拉動父文檔字符串,包括方法。所以你不必做任何事情。
確實,大多數文檔工具都是這樣做的。但內置的help()函數不會。 – MarioVilas
@MarioVilas:也許這是一個應該報告的錯誤? – naught101
不是特別優雅,但簡單而直接:
class X(object):
"""This class has a method foo()."""
def foo(): pass
class Y(X):
__doc__ = X.__doc__ + ' Also bar().'
def bar(): pass
現在:
>>> print Y.__doc__
This class has a method foo(). Also bar().
如果你想爲'Init docstring'做這個,有沒有辦法在'Y'的定義中做到這一點?我能做到的唯一方法是使用'__init __.__ doc__ = X .__ init __.__ doc__ +'另外一個參數「'在'Y'中的__init__定義之後,但這似乎與格式混亂,導致額外的增加空間。 – mgilbert
混合窗框可保留兩個繼承的文檔字符串語法和優選排序可以是:
class X(object):
"""This class has a method foo()."""
def foo(): pass
class Y(X):
""" Also bar()."""
__doc__ = X.__doc__ + __doc__
def bar(): pass
與Alex的一樣輸出:
>>> print Y.__doc__
This class has a method foo(). Also bar().
薄冰:與文檔字符串玩可以讓你的模塊無法使用與python -OO
,期待一些:
TypeError: cannot concatenate 'str' and 'NoneType' objects
我寫custom_inherit用於處理文檔字符串繼承提供一些簡單,重量輕的工具。
它還帶有一些不錯的默認樣式,用於合併不同類型的文檔字符串(例如Numpy,Google和reST格式的文檔字符串)。你也可以很容易地提供你自己的風格。
重疊的文檔字符串部分將推遲到孩子的部分,否則它們會以很好的格式合併在一起。
對於繼承父類方法的文檔字符串的方法來說,這是很整潔的。這在我認爲的許多情況下會很有用。我正在考慮更多關於整個班級的文檔字符串,我想繼承和追加。 –
啊,知道了。在這種情況下,大多數文檔都已經爲你做了。 –