oop-在Python中继承方法的文档字符串

我有一个带有文档字符串的OO层次结构,它需要与代码本身一样多的维护。 例如。,

class Swallow(object):

def airspeed(self):

"""Returns the airspeed (unladen)"""

raise NotImplementedError

class AfricanSwallow(Swallow):

def airspeed(self):

# whatever

现在,问题是_ask_arthur不继承超类方法的文档字符串。 我知道我可以使用模板方法模式来保留文档字符串,即

class Swallow(object):

def airspeed(self):

"""Returns the airspeed (unladen)"""

return self._ask_arthur()

并在每个子类中实现_ask_arthur。 但是,我想知道是否还有另一种方法来继承文档字符串,也许是我还没有发现的装饰器?

5个解决方案

23 votes

这是Paul McGuire的DocStringInheritor元类的变体。

如果子成员的文档字符串继承,则它会继承父成员的文档字符串docstring为空。

如果子类docstring为,它将继承父类docstring。空的。

它可以从以下任何类继承文档字符串任何基类的MRO,就像常规属性继承一样。

与类装饰器不同,元类是继承的,因此您只需要在某些顶级基类中设置一次元类,并且docstring继承将在整个OOP层次结构中发生。

import unittest

import sys

class DocStringInheritor(type):

"""

A variation on

http://groups.google.com/group/comp.lang.python/msg/26f7b4fcb4d66c95

by Paul McGuire

"""

def __new__(meta, name, bases, clsdict):

if not('__doc__' in clsdict and clsdict['__doc__']):

for mro_cls in (mro_cls for base in bases for mro_cls in base.mro()):

doc=mro_cls.__doc__

if doc:

clsdict['__doc__']=doc

break

for attr, attribute in clsdict.items():

if not attribute.__doc__:

for mro_cls in (mro_cls for base in bases for mro_cls in base.mro()

if hasattr(mro_cls, attr)):

doc=getattr(getattr(mro_cls,attr),'__doc__')

if doc:

if isinstance(attribute, property):

clsdict[attr] = property(attribute.fget, attribute.fset,

attribute.fdel, doc)

else:

attribute.__doc__ = doc

break

return type.__new__(meta, name, bases, clsdict)

class Test(unittest.TestCase):

def test_null(self):

class Foo(object):

def frobnicate(self): pass

class Bar(Foo, metaclass=DocStringInheritor):

pass

self.assertEqual(Bar.__doc__, object.__doc__)

self.assertEqual(Bar().__doc__, object.__doc__)

self.assertEqual(Bar.frobnicate.__doc__, None)

def test_inherit_from_parent(self):

class Foo(object):

'Foo'

def frobnicate(self):

'Frobnicate this gonk.'

class Bar(Foo, metaclass=DocStringInheritor):

pass

self.assertEqual(Foo.__doc__, 'Foo')

self.assertEqual(Foo().__doc__, 'Foo')

self.assertEqual(Bar.__doc__, 'Foo')

self.assertEqual(Bar().__doc__, 'Foo')

self.assertEqual(Bar.frobnicate.__doc__, 'Frobnicate this gonk.')

def test_inherit_from_mro(self):

class Foo(object):

'Foo'

def frobnicate(self):

'Frobnicate this gonk.'

class Bar(Foo):

pass

class Baz(Bar, metaclass=DocStringInheritor):

pass

self.assertEqual(Baz.__doc__, 'Foo')

self.assertEqual(Baz().__doc__, 'Foo')

self.assertEqual(Baz.frobnicate.__doc__, 'Frobnicate this gonk.')

def test_inherit_metaclass_(self):

class Foo(object):

'Foo'

def frobnicate(self):

'Frobnicate this gonk.'

class Bar(Foo, metaclass=DocStringInheritor):

pass

class Baz(Bar):

pass

self.assertEqual(Baz.__doc__, 'Foo')

self.assertEqual(Baz().__doc__, 'Foo')

self.assertEqual(Baz.frobnicate.__doc__, 'Frobnicate this gonk.')

def test_property(self):

class Foo(object):

@property

def frobnicate(self):

'Frobnicate this gonk.'

class Bar(Foo, metaclass=DocStringInheritor):

@property

def frobnicate(self): pass

self.assertEqual(Bar.frobnicate.__doc__, 'Frobnicate this gonk.')

if __name__ == '__main__':

sys.argv.insert(1, '--verbose')

unittest.main(argv=sys.argv)

unutbu answered 2020-01-27T02:02:29Z

22 votes

以类装饰器风格编写一个函数来为您执行复制。 在Python2.5中,您可以在创建类后直接应用它。 在更高版本中,您可以使用@decorator表示法。

这是如何做到的第一步:

import types

def fix_docs(cls):

for name, func in vars(cls).items():

if isinstance(func, types.FunctionType) and not func.__doc__:

print func, 'needs doc'

for parent in cls.__bases__:

parfunc = getattr(parent, name, None)

if parfunc and getattr(parfunc, '__doc__', None):

func.__doc__ = parfunc.__doc__

break

return cls

class Animal(object):

def walk(self):

'Walk like a duck'

class Dog(Animal):

def walk(self):

pass

Dog = fix_docs(Dog)

print Dog.walk.__doc__

在较新的Python版本中,最后一部分更加简单美观:

@fix_docs

class Dog(Animal):

def walk(self):

pass

这是一项Pythonic技术,与标准库中现有工具的设计完全匹配。 例如,functools.total_ordering类装饰器向类添加缺少的丰富比较方法。 再举一个例子,functools.wraps装饰器将元数据从一个函数复制到另一个函数。

Raymond Hettinger answered 2020-01-27T02:01:51Z

13 votes

仅供参考的FYY I人员:在Python 3.5上,inspection.getdoc自动从继承层次结构中检索文档字符串。

因此,上面的响应对于Python 2很有用,或者如果您想通过合并父母和孩子的文档字符串来变得更有创造力,那么它们很有用。

我还创建了一些用于文档字符串继承的轻量级工具。 这些支持开箱即用的一些不错的默认文档字符串样式(numpy,google,reST)。 您也可以轻松使用自己的文档字符串样式

Ryan Soklaski answered 2020-01-27T02:02:59Z

4 votes

以下适应还处理属性和mixin类。 我还遇到了不得不使用func.__func__(用于“实例方法”)的情况,但我不确定为什么其他解决方案不能解决这个问题。

def inherit_docs(cls):

for name in dir(cls):

func = getattr(cls, name)

if func.__doc__:

continue

for parent in cls.mro()[1:]:

if not hasattr(parent, name):

continue

doc = getattr(parent, name).__doc__

if not doc:

continue

try:

# __doc__'s of properties are read-only.

# The work-around below wraps the property into a new property.

if isinstance(func, property):

# We don't want to introduce new properties, therefore check

# if cls owns it or search where it's coming from.

# With that approach (using dir(cls) instead of var(cls))

# we also handle the mix-in class case.

wrapped = property(func.fget, func.fset, func.fdel, doc)

clss = filter(lambda c: name in vars(c).keys() and not getattr(c, name).__doc__, cls.mro())

setattr(clss[0], name, wrapped)

else:

try:

func = func.__func__ # for instancemethod's

except:

pass

func.__doc__ = doc

except: # some __doc__'s are not writable

pass

break

return cls

letmaik answered 2020-01-27T02:03:19Z

0 votes

def fix_docs(cls):

""" copies docstrings of derived attributes (methods, properties, attrs) from parent classes."""

public_undocumented_members = {name: func for name, func in vars(cls).items()

if not name.startswith('_') and not func.__doc__}

for name, func in public_undocumented_members.iteritems():

for parent in cls.mro()[1:]:

parfunc = getattr(parent, name, None)

if parfunc and getattr(parfunc, '__doc__', None):

if isinstance(func, property):

# copy property, since its doc attribute is read-only

new_prop = property(fget=func.fget, fset=func.fset,

fdel=func.fdel, doc=parfunc.__doc__)

cls.func = new_prop

else:

func.__doc__ = parfunc.__doc__

break

return cls

marscher answered 2020-01-27T02:03:35Z

python oop 继承_oop-在Python中继承方法的文档字符串相关推荐

  1. python html 语法高亮,在Python中使用doxygen样式文档字符串的Vim语法高亮显示

    我开始使用doxygen来生成我的Python代码的文档. 我使用doxypy过滤器来预处理Python文档字符串. 我的目标是在Python中有一个很好的语法突出显示doxygen注释. 在专用.d ...

  2. python 生成html文件浏览器,pycharm中怎么生成HTML文档并在浏览器查看HTML文档

    首先,介绍一下Python自带的pydoc模块,该模块能帮助我们生成以及查看HTML文档.(在控制台查看文档B格差了那么一丢丢,俺就没兴趣勒)待会能够熟练使用pydoc以后我们便可以直接在浏览器上打开 ...

  3. Python Tutorial中英双语对照文档5

    Python Tutorial中英双语对照文档4 CHAPTER THIRTEEN WHAT NOW? 现在咧? Reading this tutorial has probably reinforc ...

  4. Python Tutorial中英双语对照文档3

    接 Python Tutorial中英双语对照文档2 CHAPTER NINE CLASSES 类 Classes provide a means of bundling data and funct ...

  5. python中的文档字符串(docString)

    python中的文档字符串(docString) - 泥土 - 博客园 python中的文档字符串(docString) Posted on 2009-02-19 15:27 泥土 阅读(2122) ...

  6. Python批量识别图片中的文字并保存到txt文档中

    Python OCR工具pytesseract,之前是惠普的产品,被Google收了之后就给开源了. 1.需要下载并安装Google Tesseract,下载地址看图片上有,要下载4.0.0版本的 2 ...

  7. Python Tutorial中英双语对照文档1

    本文根据官方文档 http://www.pythondoc.com/pythontutorial3/ 和 中文文档 http://www.pythondoc.com/pythontutorial3/ ...

  8. Python Tutorial中英双语对照文档2

    接 Python Tutorial中英双语对照文档1 CHAPTER SIX MODULES 模块 If you quit from the Python interpreter and enter ...

  9. Python常用函数--文档字符串DocStrings

    Python 有一个甚是优美的功能称作python文档字符串(Documentation Strings),在称呼它时通常会使用另一个短一些的名字docstrings.DocStrings 是一款你应 ...

最新文章

  1. 在SQL Server 2000 和SQL Server 2005中导出表结构
  2. bo a1 蓝牙音箱 中文说明
  3. C/C++ 为什么#ifndef 头文件 要用大写加下划线?(这就是一种约定俗成的规范)
  4. DispacherServlet默认加载配置文件名
  5. for..in..遍历循环的简写模式
  6. HOW TO:构造Java类
  7. 开机自启动脚本_使用xtu降低笔记本(游戏本)cpu电压及功耗·游戏本延时(以及试着解决开机自启动的问题)...
  8. Hemberg-lab单细胞转录组数据分析(三)
  9. PVLAN技术初探-巧用PVLAN优化网络
  10. mpi和openmp混合编程的优点_混合云:拥抱云计算的未来!
  11. RocketMQ 概述
  12. 怎么连接win10共享计算机,xp系统下怎么连接win10共享的打印机
  13. 全国海关分区图(含副厅)
  14. 图论(五)单源最短路算法
  15. 外贸软件常见图片类问题丨汇信
  16. 上行带宽,下行带宽和内网带宽的区别及相关问题
  17. 虚拟同步发电机_简报︱基于分散式微电网的虚拟同步发电机无通信预同步并网方案...
  18. 华为鸿蒙os的内核是Linux,谈华为鸿蒙内核和操作系统
  19. 我的第一份CUDA代码
  20. 基于多传感器的学生课堂掌握程度评估系统和方法

热门文章

  1. java List实体排序
  2. spark on yarn 使用自定义jdk
  3. 下图所示的PCB(进程控制块)的组织方式是(),图中()。【最全!最详细分析】
  4. 26行代码AC_试题 历届试题 日期问题 | 第八届蓝桥杯B组第七题
  5. Python去线性化趋势
  6. c语言30人成绩平均分,用C语言编程平均分数
  7. Docker相关概念与安装(Docker-CE)
  8. OpenStack(一)——OpenStack与云计算概述
  9. mysql 二进制转字符串_MySql字符转义 | 学步园
  10. python笔记之利用scrapy框架爬取糗事百科首页段子