Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #52810 > unrolled thread
| Started by | Dan Sommers <dan@tombstonezero.net> |
|---|---|
| First post | 2013-08-22 05:13 +0000 |
| Last post | 2013-08-22 12:54 +0000 |
| Articles | 4 — 3 participants |
Back to article view | Back to comp.lang.python
pydoc vs. non-def'd methods Dan Sommers <dan@tombstonezero.net> - 2013-08-22 05:13 +0000
Re: pydoc vs. non-def'd methods Steven D'Aprano <steve@pearwood.info> - 2013-08-22 06:39 +0000
Re: pydoc vs. non-def'd methods Fábio Santos <fabiosantosart@gmail.com> - 2013-08-22 10:10 +0100
Re: pydoc vs. non-def'd methods Dan Sommers <dan@tombstonezero.net> - 2013-08-22 12:54 +0000
| From | Dan Sommers <dan@tombstonezero.net> |
|---|---|
| Date | 2013-08-22 05:13 +0000 |
| Subject | pydoc vs. non-def'd methods |
| Message-ID | <z5hRt.175194$cP3.153794@fx30.iad> |
Greetings,
I'm hava a class in which there are two equally useful names for one
method. Consider this design (there are other approaches, but that's
not what my question is about):
class Spam1:
def eggs(self):
'''Return the Meaning of Life.'''
return 42
ham = eggs
help(Spam1) shows that ham = eggs(self), which isn't all bad, but it
could be better. help(Spam1.ham) shows the help for eggs; I know why,
but this could be better as well. And in any case, eggs looks somehow
better than ham, because eggs has its own def statement and ham doesn't.
Now consider this design, designed to overcome the previous issues:
class Spam2:
def _private(self):
'''Return the Meaning of Life.'''
return 42
ham = _private
eggs = _private
Now help(Spam2.ham) and help(Spam2.eggs) show the same thing, but
help(Spam2) hides _private and its docstring and shows that ham and eggs
both call _private. That's no good. I can expose _private (e.g., by
renaming it to public), but that defeats the purpose of making it
private in the first place. I can go ahead and define ham to invoke
eggs, but then I have to duplicate the docstring, and it's not
being-hit-on-the-head obvious that ham and eggs are simply synonyms for
the same functionality.
I could put the documentation at the class level, but then it doesn't
show up as part of help(Spam2.eggs) or help(Spam1.ham).
So is there a clean way to define SpamN such that help(SpamN),
help(SpamN.ham), and help(SpamN.eggs) all do the Right Thing, and the
symmetry of ham and eggs is perfectly obvious to the most casual
observer?
Thanks,
Dan
[toc] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2013-08-22 06:39 +0000 |
| Message-ID | <5215b234$0$29885$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #52810 |
On Thu, 22 Aug 2013 05:13:03 +0000, Dan Sommers wrote:
> Greetings,
>
> I'm hava a class in which there are two equally useful names for one
> method. Consider this design (there are other approaches, but that's
> not what my question is about):
Generally though, one name will be the canonical or preferred name, and
the other merely an alias. That being the case, it's reasonable for the
alias to be "second class" in some fashion, as you show below.
> class Spam1:
>
> def eggs(self):
> '''Return the Meaning of Life.'''
> return 42
>
> ham = eggs
>
> help(Spam1) shows that ham = eggs(self), which isn't all bad, but it
> could be better. help(Spam1.ham) shows the help for eggs; I know why,
> but this could be better as well.
I'm not entirely sure how it could possibly be better. Since ham is just
another name for eggs, it makes sense that they show the same docstring.
> And in any case, eggs looks somehow
> better than ham, because eggs has its own def statement and ham doesn't.
I don't think I agree, but perhaps that's just an aesthetic judgement
where we disagree.
[...]
> So is there a clean way to define SpamN such that help(SpamN),
> help(SpamN.ham), and help(SpamN.eggs) all do the Right Thing, and the
> symmetry of ham and eggs is perfectly obvious to the most casual
> observer?
class Spam:
def eggs(self):
"""eggs docstring"""
return "ham and eggs"
def ham(self):
return self.eggs()
ham.__doc__ = eggs.__doc__.replace('eggs', 'ham')
This allows you two distinct docstrings, at the cost of duplicating the
information in them. Spam.ham will be a *tiny* bit less efficient, due to
the extra method call, but if you're worried about that, you're probably
up to no good :-)
But really, I would find that a confusing API. I would wonder what subtle
difference in semantics there was between ham and eggs. I would much
prefer to see that ham was just an alias:
class Spam:
def eggs(self):
"""eggs docstring"""
pass
ham = eggs
which brings us back to the beginning of your post :-)
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Fábio Santos <fabiosantosart@gmail.com> |
|---|---|
| Date | 2013-08-22 10:10 +0100 |
| Message-ID | <mailman.126.1377162643.19984.python-list@python.org> |
| In reply to | #52810 |
[Multipart message — attachments visible in raw view] — view raw
On 22 Aug 2013 06:17, "Dan Sommers" <dan@tombstonezero.net> wrote: > > Greetings, > > I'm hava a class in which there are two equally useful names for one > method. Consider this design (there are other approaches, but that's > not what my question is about): > > class Spam1: > > def eggs(self): > '''Return the Meaning of Life.''' > return 42 > > ham = eggs > > help(Spam1) shows that ham = eggs(self), which isn't all bad, but it > could be better. help(Spam1.ham) shows the help for eggs; I know why, > but this could be better as well. And in any case, eggs looks somehow > better than ham, because eggs has its own def statement and ham doesn't. > > Now consider this design, designed to overcome the previous issues: > > class Spam2: > > def _private(self): > '''Return the Meaning of Life.''' > return 42 > > ham = _private > eggs = _private > > Now help(Spam2.ham) and help(Spam2.eggs) show the same thing, but > help(Spam2) hides _private and its docstring and shows that ham and eggs > both call _private. That's no good. I can expose _private (e.g., by > renaming it to public), but that defeats the purpose of making it > private in the first place. I can go ahead and define ham to invoke > eggs, but then I have to duplicate the docstring, and it's not > being-hit-on-the-head obvious that ham and eggs are simply synonyms for > the same functionality. > > I could put the documentation at the class level, but then it doesn't > show up as part of help(Spam2.eggs) or help(Spam1.ham). > > So is there a clean way to define SpamN such that help(SpamN), > help(SpamN.ham), and help(SpamN.eggs) all do the Right Thing, and the > symmetry of ham and eggs is perfectly obvious to the most casual > observer? > > Thanks, > Dan If if one of them is the canonical method name, you could define the other with a docstring indicating it is an alias for the other. If you don't want to spend code lines you can just define a helper function for that. Heck, you can even warn a DeprecationWarning if the alias is just backwards compatibility.
[toc] | [prev] | [next] | [standalone]
| From | Dan Sommers <dan@tombstonezero.net> |
|---|---|
| Date | 2013-08-22 12:54 +0000 |
| Message-ID | <YRnRt.141116$907.107782@fx17.iad> |
| In reply to | #52810 |
On Thu, 22 Aug 2013 06:39:48 +0000, Steven D'Aprano wrote:
> On Thu, 22 Aug 2013 05:13:03 +0000, Dan Sommers wrote:
>> class Spam1:
>>
>> def eggs(self):
>> '''Return the Meaning of Life.'''
>> return 42
>>
>> ham = eggs
>>
>>
>> help(Spam1) shows that ham = eggs(self), which isn't all bad, but it
>> could be better. help(Spam1.ham) shows the help for eggs; I know
>> why, but this could be better as well.
> I'm not entirely sure how it could possibly be better. Since ham is
> just another name for eggs, it makes sense that they show the same
> docstring.
Yes, help(Spam1.eggs) and help(Spam1.ham) show the same docstring.
help(Spam1), however, doesn't show any docstring for ham; it shows that
ham = eggs(self).
>> And in any case, eggs looks somehow better than ham, because eggs has
>> its own def statement and ham doesn't.
>
> I don't think I agree, but perhaps that's just an aesthetic judgement
> where we disagree.
Yep, just the aesthetics.
> class Spam:
> def eggs(self):
> """eggs docstring"""
> return "ham and eggs"
> def ham(self):
> return self.eggs()
> ham.__doc__ = eggs.__doc__.replace('eggs', 'ham')
>
> This allows you two distinct docstrings, at the cost of duplicating
> the information in them. Spam.ham will be a *tiny* bit less efficient,
> due to the extra method call, but if you're worried about that, you're
> probably up to no good :-)
That I am up to no good goes without saying! ;-)
> But really, I would find that a confusing API. I would wonder what
> subtle difference in semantics there was between ham and eggs. I would
> much prefer to see that ham was just an alias:
>
> class Spam:
> def eggs(self):
> """eggs docstring"""
> pass
> ham = eggs
>
> which brings us back to the beginning of your post :-)
Yeah, okay, I'll go with that, despite the asymmetry. The names in
question are encrypt and decrypt, which for a stream cipher, are the
same.
Thanks, Steven, for confirming my ability to read the documentation and
play around in my interactive shell. ;-)
And Thanks, Fábio, for your suggestions, too.
--
Dan
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web