Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #87876 > unrolled thread
| Started by | Mario Figueiredo <marfig@gmail.com> |
|---|---|
| First post | 2015-03-24 09:55 +0100 |
| Last post | 2015-03-26 21:27 +1100 |
| Articles | 9 — 5 participants |
Back to article view | Back to comp.lang.python
module attributes and docstrings Mario Figueiredo <marfig@gmail.com> - 2015-03-24 09:55 +0100
Re: module attributes and docstrings Chris Angelico <rosuav@gmail.com> - 2015-03-24 21:29 +1100
Re: module attributes and docstrings Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-24 22:49 +1100
Re: module attributes and docstrings Mario Figueiredo <marfig@gmail.com> - 2015-03-26 10:48 +0100
Re: module attributes and docstrings Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-03-27 18:31 +1100
Re: module attributes and docstrings Marko Rauhamaa <marko@pacujo.net> - 2015-03-27 09:49 +0200
Re: module attributes and docstrings Terry Reedy <tjreedy@udel.edu> - 2015-03-24 15:33 -0400
Re: module attributes and docstrings Mario Figueiredo <marfig@gmail.com> - 2015-03-26 10:53 +0100
Re: module attributes and docstrings Chris Angelico <rosuav@gmail.com> - 2015-03-26 21:27 +1100
| From | Mario Figueiredo <marfig@gmail.com> |
|---|---|
| Date | 2015-03-24 09:55 +0100 |
| Subject | module attributes and docstrings |
| Message-ID | <fg92halkvjecqedpogsmkov3o53f0i922b@4ax.com> |
Reading PEP 257 and 258 I got the impression that I could document
module attributes and these would be available in the __doc__
attribute of the object.
So things like the one below are something I got used to do, but that
don't work after all, as I learned today:
value_factory = lambda _, row: row[0]
"""Row factory. To be used with single-column queries."""
There are other things I could possibly do, like turning that lambda
into a function, or document attributes in the module docstring. They
are fair responses.
But did I read docstring extraction rules in PEP 258 wrong by assuming
that the above example would make into the __doc__ attribute? And if
so, short of documenting attributes in the module docstring, is there
another way I can document individual attributes?
[toc] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-03-24 21:29 +1100 |
| Message-ID | <mailman.99.1427192988.10327.python-list@python.org> |
| In reply to | #87876 |
On Tue, Mar 24, 2015 at 7:55 PM, Mario Figueiredo <marfig@gmail.com> wrote:
> So things like the one below are something I got used to do, but that
> don't work after all, as I learned today:
>
> value_factory = lambda _, row: row[0]
> """Row factory. To be used with single-column queries."""
>
> There are other things I could possibly do, like turning that lambda
> into a function, or document attributes in the module docstring. They
> are fair responses.
They certainly are. Any time you assign a lambda function directly to
a simple name, it's probably worth replacing with a def function:
def value_factory(_, row):
"""Row factory. To be used with single-column queries."""
return row[0]
(Though I'd be inclined to give the first parameter a proper name here)
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-03-24 22:49 +1100 |
| Message-ID | <55114f5e$0$12991$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #87876 |
On Tue, 24 Mar 2015 07:55 pm, Mario Figueiredo wrote:
> Reading PEP 257 and 258 I got the impression that I could document
> module attributes and these would be available in the __doc__
> attribute of the object.
PEP 258 is rejected, so you can't take that as definitive.
PEP 257 has this definition very early in the document:
A docstring is a string literal that occurs as the first
statement in a module, function, class, or method definition.
Nothing there about documenting arbitrary attributes.
The PEP does go on to say:
String literals occurring elsewhere in Python code may also
act as documentation. They are not recognized by the Python
bytecode compiler and are not accessible as runtime object
attributes (i.e. not assigned to __doc__ ), but two types
of extra docstrings may be extracted by software tools: ...
so if I write this:
class K:
x = something()
"""Documentation for x"""
then the string *may* be extracted by certain third-party tools, but it will
not be recognised as a docstring by the Python interpreter and will not be
available as the __doc__ attribute of K.x.
> So things like the one below are something I got used to do, but that
> don't work after all, as I learned today:
>
> value_factory = lambda _, row: row[0]
> """Row factory. To be used with single-column queries."""
>
> There are other things I could possibly do, like turning that lambda
> into a function, or document attributes in the module docstring. They
> are fair responses.
For the record, the lambda is already a function. lambda is just an
alternative syntax for creating functions, not a different kind of object.
> But did I read docstring extraction rules in PEP 258 wrong by assuming
> that the above example would make into the __doc__ attribute? And if
> so, short of documenting attributes in the module docstring, is there
> another way I can document individual attributes?
In a word, no.
Even if there was support from the compiler to extract the docstring, where
would it be stored? Consider:
spam = None
"""Spammy goodness."""
eggs = None
"""Scrambled, not fried."""
There's only one None object, and even if it could take a docstring (and it
can't), which docstring would it get? Presumably the second, which would
make help(spam) confusing, but when we say eggs = 23 the docstring would
disappear too.
Python's data model is not compatible with the idea of associating
docstrings with arbitrary attributes or variables. The docstring has to be
associated with an object, and only certain objects at that.
That applies to documentation which is introspectable at runtime. But of
course you can do anything you like by parsing the source code! It may be
that the docutils library will parse the source code and extract
docstrings, associating them to their variable or attribute. If not,
perhaps some other third-party library, or you can write your own.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Mario Figueiredo <marfig@gmail.com> |
|---|---|
| Date | 2015-03-26 10:48 +0100 |
| Message-ID | <ljk7happp134fau09h37893ed1m6n3gmaf@4ax.com> |
| In reply to | #87878 |
Sorry for the late reply. We experienced a 3 day blackout following one of the most amazing thunderstorms I've witnessed in my life. On Tue, 24 Mar 2015 22:49:49 +1100, Steven D'Aprano <steve+comp.lang.python@pearwood.info> wrote: >On Tue, 24 Mar 2015 07:55 pm, Mario Figueiredo wrote: > >> Reading PEP 257 and 258 I got the impression that I could document >> module attributes and these would be available in the __doc__ >> attribute of the object. > >PEP 258 is rejected, so you can't take that as definitive. Ah! That explains it then. Thank you. (Also learned to start paying more attention to the status field). > >PEP 257 has this definition very early in the document: > > A docstring is a string literal that occurs as the first > statement in a module, function, class, or method definition. > > >Nothing there about documenting arbitrary attributes. That did get me a little confused. But since PEP 258 required PEP 257, I just assumed the former would redefine the latter and didn't make much of the apparent contradiction. > >Even if there was support from the compiler to extract the docstring, where >would it be stored? Consider: > >spam = None >"""Spammy goodness.""" >eggs = None >"""Scrambled, not fried.""" > >There's only one None object, and even if it could take a docstring (and it >can't), which docstring would it get? Presumably the second, which would >make help(spam) confusing, but when we say eggs = 23 the docstring would >disappear too. This is a byproduct of me still thinking in terms of C variables. When I first read that paragraph of yours, it didn't make sense to me -- "What is he talking about? I'm documenting the spam and eggs identifiers, not the None object". But when I was trying to reply to you by mounting a case around writing directly to the __doc__ attribute of the spam and eggs identifiers, the python shell was quick to make me realized my foolishness, and I remembered about Python variables not being the same as C variables.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2015-03-27 18:31 +1100 |
| Message-ID | <55150749$0$13004$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #88037 |
On Thu, 26 Mar 2015 08:48 pm, Mario Figueiredo wrote: > Sorry for the late reply. We experienced a 3 day blackout following > one of the most amazing thunderstorms I've witnessed in my life. Wow. Where abouts are you? Apart from the blackout, did you get through it alright? More below... > On Tue, 24 Mar 2015 22:49:49 +1100, Steven D'Aprano > <steve+comp.lang.python@pearwood.info> wrote: [...] >>Even if there was support from the compiler to extract the docstring, >>where would it be stored? Consider: >> >>spam = None >>"""Spammy goodness.""" >>eggs = None >>"""Scrambled, not fried.""" >> >>There's only one None object, and even if it could take a docstring (and >>it can't), which docstring would it get? Presumably the second, which >>would make help(spam) confusing, but when we say eggs = 23 the docstring >>would disappear too. > > This is a byproduct of me still thinking in terms of C variables. When > I first read that paragraph of yours, it didn't make sense to me -- > "What is he talking about? I'm documenting the spam and eggs > identifiers, not the None object". > > But when I was trying to reply to you by mounting a case around > writing directly to the __doc__ attribute of the spam and eggs > identifiers, the python shell was quick to make me realized my > foolishness, and I remembered about Python variables not being the > same as C variables. Yes, that's exactly it! Some people prefer to say "Python has no variables, it has name bindings". I think that it's better to say that Python's variables are not *like* C or Pascal variables, rather than invent a distinction between name bindings and variables. Name bindings are a type of variable. -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Marko Rauhamaa <marko@pacujo.net> |
|---|---|
| Date | 2015-03-27 09:49 +0200 |
| Message-ID | <87lhiinalm.fsf@elektro.pacujo.net> |
| In reply to | #88137 |
Steven D'Aprano <steve+comp.lang.python@pearwood.info>: > Some people prefer to say "Python has no variables, it has name > bindings". I think that it's better to say that Python's variables are > not *like* C or Pascal variables, rather than invent a distinction > between name bindings and variables. Name bindings are a type of > variable. I guess the thinking goes like this: In Python, everything is a first-class object. In Python, variables are not first-class objects. Ergo: In Python, there are no variables. Marko
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2015-03-24 15:33 -0400 |
| Message-ID | <mailman.110.1427225646.10327.python-list@python.org> |
| In reply to | #87876 |
On 3/24/2015 4:55 AM, Mario Figueiredo wrote: > Reading PEP 257 and 258 I got the impression that I could document > module attributes and these would be available in the __doc__ > attribute of the object. > > So things like the one below are something I got used to do, but that > don't work after all, as I learned today: > > value_factory = lambda _, row: row[0] > """Row factory. To be used with single-column queries.""" > > There are other things I could possibly do, like turning that lambda > into a function, You have discovered one of advantages of a def statement over a name=lambda assignment statement. In Python, there is no good reason to use the latter form and PEP 8 specifically discourages it: "Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier." -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Mario Figueiredo <marfig@gmail.com> |
|---|---|
| Date | 2015-03-26 10:53 +0100 |
| Message-ID | <cgl7hadtmma78b3g2617tr0f19897gm7tu@4ax.com> |
| In reply to | #87895 |
On Tue, 24 Mar 2015 15:33:41 -0400, Terry Reedy <tjreedy@udel.edu> wrote: > >You have discovered one of advantages of a def statement over a >name=lambda assignment statement. In Python, there is no good reason to >use the latter form and PEP 8 specifically discourages it: "Always use a >def statement instead of an assignment statement that binds a lambda >expression directly to an identifier." Chris also suggested me this. And frankly, I don't see why I shouldn't follow that advise. It's good advice. However, lambda functions do read well in my mind and I find it hard to spot where they obscure the code more than a function. So the explicit vs. implicit part of the argument doesn't translate well with me. I however agree that a function declaration brings other benefits, like the ability to decorate or document. I will reserve the use of lambdas to only where they are necessary. Thanks.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2015-03-26 21:27 +1100 |
| Message-ID | <mailman.193.1427365668.10327.python-list@python.org> |
| In reply to | #88038 |
On Thu, Mar 26, 2015 at 8:53 PM, Mario Figueiredo <marfig@gmail.com> wrote: > However, lambda functions do read well in my mind and I find it hard > to spot where they obscure the code more than a function. So the > explicit vs. implicit part of the argument doesn't translate well with > me. I however agree that a function declaration brings other benefits, > like the ability to decorate or document. A function is a function is a function, so really, it's just a question of whether you create them with a statement (def) or an expression (lambda). Two basic rules of thumb: 1) If you're assigning a lambda function to a simple name, then you don't need it to be an expression, so use def. 2) If you're warping your function body to make it an expression, use def. Basically, look at the outside and look at the inside. In some cases, it's obvious that it's all expressions: # Sort a list of widget objects by name widgets.sort(key=lambda w: w.name) Other times, it's pretty obvious that you should be using statements: delete_name_if_blank = lambda w: delattr(w, "name") if w.name == "" else None list(map(delete_name_if_blank, widgets)) In between, there's a lot of room to call it either way. ChrisA
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web