日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

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

發布時間:2024/1/23 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python oop 继承_oop-在Python中继承方法的文档字符串 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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中继承方法的文档字符串的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。