Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!feeder.news-service.com!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'help?': 0.03; 'sys': 0.05; 'command-line': 0.09; 'subclass': 0.09; 'def': 0.12; 'am,': 0.14; 'wrote:': 0.14; '-tkc': 0.16; '@property': 0.16; '[1].': 0.16; 'docstring': 0.16; 'from:addr:python.list': 0.16; 'from:addr:tim.thechases.com': 0.16; 'from:name:tim chase': 0.16; 'go?': 0.16; 'inherit,': 0.16; 'message-id:@tim.thechases.com': 0.16; 'metaclasses': 0.16; 'occasionally': 0.16; 'properties.': 0.16; 'runtime.': 0.16; 'stdout': 0.16; 'what?': 0.16; 'matching': 0.16; 'skip:" 40': 0.16; 'cc:addr:python-list': 0.17; 'header:In- Reply-To:1': 0.21; '(like': 0.21; 'cc:2**0': 0.22; 'picking': 0.23; 'code': 0.24; "doesn't": 0.25; 'pass': 0.27; 'helpful': 0.28; 'skip:" 30': 0.29; 'subject:how': 0.29; 'subject:?': 0.29; 'import': 0.29; 'class.': 0.29; 'class': 0.29; 'cc:addr:python.org': 0.30; 'decorators': 0.30; 'print': 0.31; 'seem': 0.32; 'asking': 0.33; 'things': 0.33; "i've": 0.33; 'header:User-Agent:1': 0.35; 'skip:" 10': 0.35; 'using': 0.35; 'test': 0.35; 'similar': 0.37; 'something': 0.37; 'eric': 0.38; 'subject:: ': 0.38; 'some': 0.38; 'sometimes': 0.39; 'perhaps': 0.39; 'received:209': 0.39; 'help': 0.40; 'below.': 0.65; '(after': 0.67; '01:22': 0.84; 'datetime': 0.84; 'snow': 0.91; 'inheritance,': 0.93 Date: Fri, 10 Jun 2011 06:05:47 -0500 From: Tim Chase User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.17) Gecko/20110414 Thunderbird/3.1.10 MIME-Version: 1.0 To: Eric Snow Subject: Re: how to inherit docstrings? References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - boston.accountservergroup.com X-AntiAbuse: Original Domain - python.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tim.thechases.com X-Source: X-Source-Args: X-Source-Dir: Cc: python-list X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 62 NNTP-Posting-Host: 82.94.164.166 X-Trace: 1307703964 news.xs4all.nl 49175 [::ffff:82.94.164.166]:33461 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:7374 On 06/09/2011 01:22 AM, Eric Snow wrote: > Sometimes when using class inheritance, I want the overriding methods > of the subclass to get the docstring of the matching method in the > base class. You can do this with decorators (after the class > definition), with class decorators, and with metaclasses [1]. While asking for __doc__ ponies and picking colors for bike-sheds, in a similar vein, I've occasionally wanted to do something like class Foo: @property def __doc__(self): return dynamically_generated_string # perhaps using introspection This would have been most helpful in things like generating help (like in command-line parsers), where the doc-string can introspect the class and learn about its methods at runtime. Some things seem to inherit, some don't, and help() doesn't seem to pick up on any of the dynamically-defined __doc__ properties. Test code below. -tkc from datetime import datetime from sys import stdout class Base(object): "Base docstring" @property def __doc__(self): return datetime.now().strftime('%c') class WithDoc(Base): "WithDoc docstring" pass class WithoutDoc(Base): pass base = Base() has = WithDoc() lacks = WithoutDoc() for test in ( "help(base)", # why not in help? "help(has)", # expected "help(lacks)", # why not in help? "help(Base)", "help(WithDoc)", # expected "help(WithoutDoc)", "stdout.write(repr(base.__doc__))", # works "stdout.write(repr(has.__doc__))", # expected "stdout.write(repr(lacks.__doc__))", # where'd it go? "stdout.write(repr(Base.__doc__))", # expected "stdout.write(repr(WithDoc.__doc__))", # expected "stdout.write(repr(WithoutDoc.__doc__))", # what? ): print test eval(test) print