With feedback from Guido, Barry, Raymond and others, I have updated PEP 8 to better describe our current development practices. It started as an update to describe the different between public and internal interfaces and to advise against using wildcard imports, but became substantially more :) For those that want full details, the relevant commit and tracker issue are here: http://hg.python.org/peps/rev/fb24c80e9afb http://bugs.python.org/issue18472 If you're responsible for a coding standard that includes PEP 8 by reference, you probably want to take a look at these :) For everyone else, here are the highlights: 1. Made it clear this is a living document (using the approach of creating a tracker issue for major updates and adding a new footnote referencing that issue) 2. Added more specific points to the "foolish consistency" section to help out those folks resisting pointless PEP 8 compliance for code that predates the existence of the PEP's recommendations. 3. Stopped being wishy-washy about tabs vs spaces. Use spaces :) 4. Lines up to 99 characters are now permitted (but 79 is still the preferred limit) 5. The encodings section is now emphatically in favour of UTF-8 (latin-1 is no longer even mentioned) 6. While absolute imports are still favoured, explicit relative imports are deemed acceptable 7. Wildcard imports are strongly discouraged for most cases (with dynamic republishing the only acceptable use case, since PEP 8 doesn't apply at all for the interactive prompt) 8. New section explaining the distinction between public and internal interfaces (and how to tell which is which) 9. Explicit guideline not to assign lambdas to names (use def, that's what it's for) 10. Various tweaks to the exception raising and handling guidelines 11. Explicit recommendation to use a decorator in conjunction with annotations in third party experiments Cheers, Nick. P.S. It's possible this should also be published through python-announce and other channels... -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
On Thu, Aug 1, 2013 at 9:10 AM, Antoine Pitrou
Something magic about 99?
I'm guessing it's short enough you can say you tried, but long enough to annoy traditionalists anyway. I'm annoyed already. :-) -Fred -- Fred L. Drake, Jr. <fred at fdrake.net> "A storm broke loose in my mind." --Albert Einstein
On Thu, 01 Aug 2013 09:16:13 -0400, Fred Drake
On Thu, Aug 1, 2013 at 9:10 AM, Antoine Pitrou
wrote: Something magic about 99?
I'm guessing it's short enough you can say you tried, but long enough to annoy traditionalists anyway.
I'm annoyed already. :-)
+1 :) My terminal windows are usually wider than 80 chars, but I still find it far far better to limit myself to 79 columns, because it gives me the flexibility to narrow the windows at need (eg: :vsplit in vi to see several files side-by-side). The (small) improvement in readability of longer lines is far less significant to me than the loss of readability when I want narrower windows (or run into them in code review tools, as mentioned). But of course this is just my opinion :) :) --David
On Thu, Aug 1, 2013 at 10:21 AM, R. David Murray
I'm guessing it's short enough you can say you tried, but long enough to annoy traditionalists anyway.
I'm annoyed already. :-)
+1 :)
+1 :) I recently gave up and reset default auto-wrap margin to 120 locally. This change had little effect on code because most line breaks in code are inserted manually anyways. However, docstrings are beginning to suffer. The "short description" line is not that short anymore and multi-paragraph prose filled between 4- and 120-characters margin is hard to read. I will start experimenting with 100-char limit, but I think it is still too wide for auto-wrapped text. Maybe we should have a stronger recommendation to keep 80-char limit for docstrings and other embedded text. It is OK to have an occasional long line in code, but readability suffers when you have every line close to 100 chars. Another observation is that long lines in code are usually heavily indented. This makes them still readable because non-white characters still fit within the field of view. Again, this is not the case for docstrings, comments or other embedded prose.
On Aug 01, 2013, at 11:05 AM, Alexander Belopolsky wrote:
I will start experimenting with 100-char limit, but I think it is still too wide for auto-wrapped text. Maybe we should have a stronger recommendation to keep 80-char limit for docstrings and other embedded text. It is OK to have an occasional long line in code, but readability suffers when you have every line close to 100 chars.
In general, long lines are a smell that the code is trying to express something too complex or is being too clever. Using various strategies judiciously usually leads to better, more readable code (e.g. use a local variable, wrap the line after open parens, don't chain too many calls, etc.) I'm not counting exceptions of course, it's PEP 8 after all! So I would greatly prefer that stdlib files be kept to the 79 character limit. I see most violations of this in the library documents, but especially there, paragraphs should be wrapped to 79 characters, and can easily be done without losing expressability. Cheers, -Barry
On Thu, 01 Aug 2013 11:35:38 -0400, Barry Warsaw
So I would greatly prefer that stdlib files be kept to the 79 character limit. I see most violations of this in the library documents, but especially there, paragraphs should be wrapped to 79 characters, and can easily be done without losing expressability.
The documentation often has line lengths longer than 80 chars for two reasons: (1) the original translation from TeX was done by a script, and the script had a bug in it that made the lines slightly too long, and no one noticed in time and (2) until relatively recently Sphinx didn't support wrapping prototype lines (it now does). So as we edit the docs, we re-wrap. Just like we do with the legacy code :) The code examples in the docs are a bit trickier, since if you wrap the source to 79 you wind up with even-shorter-than-79 wrapping in the actual code lines, which can look odd when the text is rendered. So there it's a judgement call...but I still generally try to wrap the source to 79, sometimes refactoring the example to make that more elegant. Which, as you point out, often makes it better as well :). --David
On 2 Aug 2013 01:18, "Alexander Belopolsky"
On Thu, Aug 1, 2013 at 10:21 AM, R. David Murray
I'm guessing it's short enough you can say you tried, but long enough to annoy traditionalists anyway.
I'm annoyed already. :-)
+1 :)
+1 :)
I recently gave up and reset default auto-wrap margin to 120 locally. This change had little effect on code because most line breaks in code are inserted manually anyways. However, docstrings are beginning to suffer. The "short description" line is not that short anymore and multi-paragraph
wrote: prose filled between 4- and 120-characters margin is hard to read.
I will start experimenting with 100-char limit, but I think it is still
too wide for auto-wrapped text. Maybe we should have a stronger recommendation to keep 80-char limit for docstrings and other embedded text. It is OK to have an occasional long line in code, but readability suffers when you have every line close to 100 chars. 1. The recommended length limit for flowed text is still *72* (since it doesn't have the structural constraints code does). 2. The preferred length limit for code is still 79. The "up to 99 if it improves readability" escape clause was added because Guido deemed the occasional long line a lesser evil than the contortions he has seen people apply to code to stay within the 79 character limit (most notably, using cryptic variable names because they're shorter). That entire section of the PEP was completely rewritten - we didn't just s/79/99/ with the old content. Cheers, Nick.
Another observation is that long lines in code are usually heavily
indented. This makes them still readable because non-white characters still fit within the field of view. Again, this is not the case for docstrings, comments or other embedded prose.
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe:
http://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com
On 1 August 2013 23:10, Antoine Pitrou
Le Thu, 1 Aug 2013 22:44:12 +1000, Nick Coghlan
a écrit : 4. Lines up to 99 characters are now permitted (but 79 is still the preferred limit)
Something magic about 99?
One less than 100, same as 79 is one less than 80. The "100" came from Guido :) Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia
Le Thu, 1 Aug 2013 23:21:49 +1000,
Nick Coghlan
On 1 August 2013 23:10, Antoine Pitrou
wrote: Le Thu, 1 Aug 2013 22:44:12 +1000, Nick Coghlan
a écrit : 4. Lines up to 99 characters are now permitted (but 79 is still the preferred limit)
Something magic about 99?
One less than 100, same as 79 is one less than 80. The "100" came from Guido :)
Yes, I've heard about those spiffy BCD computers in the powerful datacenters of American companies :-) (and after all, BCD == ABC + 1) Regards Antoine.
On 01/08/13 22:44, Nick Coghlan wrote:
4. Lines up to 99 characters are now permitted (but 79 is still the preferred limit)
Coincidentally, there was a discussion about line length on python-list over the last couple of days. I think the two most relevant comments are by Skip Montanaro: http://mail.python.org/pipermail/python-list/2013-July/652977.html http://mail.python.org/pipermail/python-list/2013-July/653046.html If I may be permitted to paraphrase: - publishers and printers have been dealing with readability of text for an awfully long time, and they pretty much all use a de facto standard of 70-80 characters per line; - most lines of code are short, stretching the max out to 100 characters when most lines are around 60 just ends up wasting screen real estate if your editor window is wide enough to deal with the max. To that last point, I add: it's even worse if you keep the editor relatively narrow, since now you have a few lines that require horizontal scrolling, which is awful, or line-wrapping, neither of which are palatable. -- Steven
On Thu, Aug 1, 2013 at 8:31 AM, Steven D'Aprano
On 01/08/13 22:44, Nick Coghlan wrote:
4. Lines up to 99 characters are now permitted (but 79 is still the
preferred limit)
Coincidentally, there was a discussion about line length on python-list over the last couple of days. I think the two most relevant comments are by Skip Montanaro:
http://mail.python.org/**pipermail/python-list/2013-**July/652977.htmlhttp://mail.python.org/pipermail/python-list/2013-July/652977.html http://mail.python.org/**pipermail/python-list/2013-**July/653046.htmlhttp://mail.python.org/pipermail/python-list/2013-July/653046.html
I believe there may be a relationship to the 7 plus or minus 2 (times 10) of human conceptual limits. Personally I find it very difficult to read text with long lines. Historically two or three column (newspaper/book) with a barrier margin was used to get much more text on the page, but still the reader had much shorter "chunks" to absorb.
If I may be permitted to paraphrase:
- publishers and printers have been dealing with readability of text for an awfully long time, and they pretty much all use a de facto standard of 70-80 characters per line;
- most lines of code are short, stretching the max out to 100 characters when most lines are around 60 just ends up wasting screen real estate if your editor window is wide enough to deal with the max.
To that last point, I add: it's even worse if you keep the editor relatively narrow, since now you have a few lines that require horizontal scrolling, which is awful, or line-wrapping, neither of which are palatable.
-- Steven
______________________________**_________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/**mailman/listinfo/python-devhttp://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/**mailman/options/python-dev/** ldlandis%40gmail.comhttp://mail.python.org/mailman/options/python-dev/ldlandis%40gmail.com
-- --- NOTE: If it is important CALL ME - I may miss email, which I do NOT normally check on weekends nor on a regular basis during any other day. --- LD Landis - N0YRQ - de la tierra del encanto 3960 Schooner Loop, Las Cruces, NM 88012 651-340-4007 N32 21'48.28" W106 46'5.80"
http://mail.python.org/pipermail/python-list/2013-July/653046.html
One correspondent objected that I was artificial biasing my histogram because wrapped lines are, more-or-less by definition, going to be < 80 characters. Off-list I responded with a modified version of my graph where I eliminated all lines which ended in my preferred continuation characters (open paren-like things and commas). The resulting histogram is attached (count as a function of line length). This makes the "wasted space" argument even stronger. Generally, when I wrap a line, I wrap it fairly near the limit, so by eliminating them, the shorter lines stand out more clearly. Skip
On 1 Aug, 2013, at 16:34, Alexander Shorin
Hi Nick,
On Thu, Aug 1, 2013 at 4:44 PM, Nick Coghlan
wrote: 9. Explicit guideline not to assign lambdas to names (use def, that's what it's for)
Even for propose to fit chars-per-line limit and/or to remove duplicates (especially for sorted groupby case)?
When you do "name = lambda ..." you've created a named function, when you do that your better of using def statement for the reasons Nick mentioned in the PEP. Ronald
-- ,,,^..^,,, _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ronaldoussoren%40mac.com
Hi Ronald,
I understand this, but I'm a bit confused about fate of lambdas with
such guideline since I see no more reasons to use them with p.9
statement: long lines, code duplicate, no mock and well tests etc. -
all these problems could be solved with assigning lambda to some name,
but now they are looks useless (or useful only for very trivial cases)
--
,,,^..^,,,
On Thu, Aug 1, 2013 at 6:41 PM, Ronald Oussoren
On 1 Aug, 2013, at 16:34, Alexander Shorin
wrote: Hi Nick,
On Thu, Aug 1, 2013 at 4:44 PM, Nick Coghlan
wrote: 9. Explicit guideline not to assign lambdas to names (use def, that's what it's for)
Even for propose to fit chars-per-line limit and/or to remove duplicates (especially for sorted groupby case)?
When you do "name = lambda ..." you've created a named function, when you do that your better of using def statement for the reasons Nick mentioned in the PEP.
Ronald
-- ,,,^..^,,, _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ronaldoussoren%40mac.com
On 1 Aug, 2013, at 16:48, Alexander Shorin
Hi Ronald,
I understand this, but I'm a bit confused about fate of lambdas with such guideline since I see no more reasons to use them with p.9 statement: long lines, code duplicate, no mock and well tests etc. - all these problems could be solved with assigning lambda to some name, but now they are looks useless (or useful only for very trivial cases)
That sounds about right :-) Note that: f = lambda x: x ** 2 And: def f(x): return x ** 2 Are functionally equivalent and use the same byte code. The only differences are that the lambda saves two characters in typing, and the "def" variant has a more useful value in its __name__ attribute. IMHO The lambda variant also looks uglier (even with the def variant on a single line). Ronald
-- ,,,^..^,,,
On Thu, Aug 1, 2013 at 6:41 PM, Ronald Oussoren
wrote: On 1 Aug, 2013, at 16:34, Alexander Shorin
wrote: Hi Nick,
On Thu, Aug 1, 2013 at 4:44 PM, Nick Coghlan
wrote: 9. Explicit guideline not to assign lambdas to names (use def, that's what it's for)
Even for propose to fit chars-per-line limit and/or to remove duplicates (especially for sorted groupby case)?
When you do "name = lambda ..." you've created a named function, when you do that your better of using def statement for the reasons Nick mentioned in the PEP.
Ronald
-- ,,,^..^,,, _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ronaldoussoren%40mac.com
...and, if so, why lambda's?(: Without backward compatibility point I
see that they are getting "unofficially" deprecated and their usage is
dishonoured.
--
,,,^..^,,,
On Thu, Aug 1, 2013 at 6:53 PM, Ronald Oussoren
On 1 Aug, 2013, at 16:48, Alexander Shorin
wrote: Hi Ronald,
I understand this, but I'm a bit confused about fate of lambdas with such guideline since I see no more reasons to use them with p.9 statement: long lines, code duplicate, no mock and well tests etc. - all these problems could be solved with assigning lambda to some name, but now they are looks useless (or useful only for very trivial cases)
That sounds about right :-)
Note that:
f = lambda x: x ** 2
And:
def f(x): return x ** 2
Are functionally equivalent and use the same byte code. The only differences are that the lambda saves two characters in typing, and the "def" variant has a more useful value in its __name__ attribute.
IMHO The lambda variant also looks uglier (even with the def variant on a single line).
Ronald
-- ,,,^..^,,,
On Thu, Aug 1, 2013 at 6:41 PM, Ronald Oussoren
wrote: On 1 Aug, 2013, at 16:34, Alexander Shorin
wrote: Hi Nick,
On Thu, Aug 1, 2013 at 4:44 PM, Nick Coghlan
wrote: 9. Explicit guideline not to assign lambdas to names (use def, that's what it's for)
Even for propose to fit chars-per-line limit and/or to remove duplicates (especially for sorted groupby case)?
When you do "name = lambda ..." you've created a named function, when you do that your better of using def statement for the reasons Nick mentioned in the PEP.
Ronald
-- ,,,^..^,,, _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ronaldoussoren%40mac.com
On 1 Aug, 2013, at 17:03, Alexander Shorin
...and, if so, why lambda's?(: Without backward compatibility point I see that they are getting "unofficially" deprecated and their usage is dishonoured.
They are still usefull for simple functions that you use in one place, such as the key argument to sorted. By the time you assign a name to the function and give it unittests you may as well use a def-statement and let the function know it its own name. Ronald
-- ,,,^..^,,,
On Thu, Aug 1, 2013 at 6:53 PM, Ronald Oussoren
wrote: On 1 Aug, 2013, at 16:48, Alexander Shorin
wrote: Hi Ronald,
I understand this, but I'm a bit confused about fate of lambdas with such guideline since I see no more reasons to use them with p.9 statement: long lines, code duplicate, no mock and well tests etc. - all these problems could be solved with assigning lambda to some name, but now they are looks useless (or useful only for very trivial cases)
That sounds about right :-)
Note that:
f = lambda x: x ** 2
And:
def f(x): return x ** 2
Are functionally equivalent and use the same byte code. The only differences are that the lambda saves two characters in typing, and the "def" variant has a more useful value in its __name__ attribute.
IMHO The lambda variant also looks uglier (even with the def variant on a single line).
Ronald
-- ,,,^..^,,,
On Thu, Aug 1, 2013 at 6:41 PM, Ronald Oussoren
wrote: On 1 Aug, 2013, at 16:34, Alexander Shorin
wrote: Hi Nick,
On Thu, Aug 1, 2013 at 4:44 PM, Nick Coghlan
wrote: 9. Explicit guideline not to assign lambdas to names (use def, that's what it's for)
Even for propose to fit chars-per-line limit and/or to remove duplicates (especially for sorted groupby case)?
When you do "name = lambda ..." you've created a named function, when you do that your better of using def statement for the reasons Nick mentioned in the PEP.
Ronald
-- ,,,^..^,,, _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/ronaldoussoren%40mac.com
On Thu, Aug 1, 2013 at 11:03 AM, Alexander Shorin
...and, if so, why lambda's?(: Without backward compatibility point I see that they are getting "unofficially" deprecated and their usage is dishonored.
Here is one use-case where .. = lambda .. cannot be replaced with def .. op['add'] = lambda x,y: x+y op['mul'] = lambda x, y: x*y ..
On 8/1/2013 11:35 AM, Alexander Belopolsky wrote:
Here is one use-case where .. = lambda .. cannot be replaced with def ..
op['add'] = lambda x,y: x+y op['mul'] = lambda x, y: x*y
Yes, you are binding the functions to named slots, not to names, so not
covered by the PEP. Once might still want to replace the expressions
themselves, at the cost of more typing, for the advantage of better
representations.
op = { 'add': lambda x,y: x*y, 'mul': lambda x, y: x+y}
print(op) # no apparent problem
# {'add':
Hi Terry,
On Fri, Aug 2, 2013 at 12:29 AM, Terry Reedy
def f(x): return 2*x f = lambda x: 2*x Three spaces is seldom a crucial difference. If the expression is so long it go past the limit (whatever we decide it is), it can be wrapped.
and if I have multiple lambda-like def`s it will hit the PEP rule :
While sometimes it's okay to put an if/for/while with a small body on the same line, never do this for multi-clause statements. Also avoid folding such long lines!
On Fri, Aug 2, 2013 at 12:29 AM, Terry Reedy
and/or to remove duplicates (especially for sorted groupby case)? I do not understand this.
See [Python-Dev] Lambda [was Re: PEP 8 modernisation] thread for example:
http://mail.python.org/pipermail/python-dev/2013-August/127715.html
On Fri, Aug 2, 2013 at 12:35 AM, Terry Reedy
I understand this, but I'm a bit confused about fate of lambdas with such guideline since I see no more reasons to use them with p.9 statement: long lines, code duplicate, no mock and well tests etc. - all these problems could be solved with assigning lambda to some name, but now they are looks useless (or useful only for very trivial cases)
I do not understand most of that, but... The guideline is not meant to cover passing a function by parameter name. mylist.sort(key=lambda x: x[0]) is still ok. Does "Always use a def statement >instead of assigning a lambda expression to a name." need 'in an assignment statement' added?
I wrote about that lambda`s use case become too small to use them in real code. If they are dishonoured - need to write so and clearly, but not limiting their use cases step by step till every Python devs will think like "Lambdas? Why? Remove them!". Using `dict` to store lambdas:
op = { 'add': lambda x,y: x*y, 'mul': lambda x, y: x+y}
Shows the hack to bypass PEP8 guides. Do you like to see code above instead of:
add = lambda x,y: x*y
mul = lambda x, y: x+y
Probably, I don't since dict is a blackbox and I have to check things
first before use them.
Disclaimer: I don't try to stand for lambdas, I'm not using them
everywhere in my code, but I'd like to know answer for the question
"Why lambdas?". Currently, it is "Handy shorthand functions - use them
free", but with new PEP-8 statement I really have to think like
"Lambdas? Really, why?".
P.S.
On Thu, Aug 1, 2013 at 3:36 PM, Terry Reedy
Please stop both the top-posting and the FUD.
Sorry, different ML, different rules. You know mail client with allows
to have per-address reply setting? I don't, but would like to see your
suggestions in private answer. Thanks.
--
,,,^..^,,,
On Fri, Aug 2, 2013 at 12:56 AM, Terry Reedy
On 8/1/2013 11:35 AM, Alexander Belopolsky wrote:
Here is one use-case where .. = lambda .. cannot be replaced with def ..
op['add'] = lambda x,y: x+y op['mul'] = lambda x, y: x*y
Yes, you are binding the functions to named slots, not to names, so not covered by the PEP. Once might still want to replace the expressions themselves, at the cost of more typing, for the advantage of better representations.
op = { 'add': lambda x,y: x*y, 'mul': lambda x, y: x+y} print(op) # no apparent problem # {'add':
, # 'mul': } def add(x, y): return x + y def mul(x, y): return x * y # These can be unittested individually
op = {'add': mul, 'mul': add} # mistake easily seen in original code print(op) # {'add':
, # 'mul': } # problem apparent to user who import this object and prints it when code fails If op has 20 such functions, names become even more of an advantage
-- Terry Jan Reedy
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/kxepal%40gmail.com
On 2 Aug 2013 17:31, "Alexander Shorin"
Hi Terry,
On Fri, Aug 2, 2013 at 12:29 AM, Terry Reedy
wrote: def f(x): return 2*x f = lambda x: 2*x Three spaces is seldom a crucial difference. If the expression is so
long it go past the limit (whatever we decide it is), it can be wrapped.
and if I have multiple lambda-like def`s it will hit the PEP rule :
While sometimes it's okay to put an if/for/while with a small body on
the same line, never do this for multi-clause statements. Also avoid folding such long lines!
On Fri, Aug 2, 2013 at 12:29 AM, Terry Reedy
wrote: and/or to remove duplicates (especially for sorted groupby case)? I do not understand this.
See [Python-Dev] Lambda [was Re: PEP 8 modernisation] thread for example: http://mail.python.org/pipermail/python-dev/2013-August/127715.html
On Fri, Aug 2, 2013 at 12:35 AM, Terry Reedy
wrote: I understand this, but I'm a bit confused about fate of lambdas with such guideline since I see no more reasons to use them with p.9 statement: long lines, code duplicate, no mock and well tests etc. - all these problems could be solved with assigning lambda to some name, but now they are looks useless (or useful only for very trivial cases)
I do not understand most of that, but... The guideline is not meant to cover passing a function by parameter
name. mylist.sort(key=lambda x: x[0]) is still ok. Does "Always use a def statement >instead of assigning a lambda expression to a name." need 'in an assignment statement' added?
I wrote about that lambda`s use case become too small to use them in real code. If they are dishonoured - need to write so and clearly, but not limiting their use cases step by step till every Python devs will think like "Lambdas? Why? Remove them!".
Lambda was almost removed in Python 3.
Using `dict` to store lambdas:
op = { 'add': lambda x,y: x*y, 'mul': lambda x, y: x+y}
Shows the hack to bypass PEP8 guides. Do you like to see code above
instead of:
add = lambda x,y: x*y mul = lambda x, y: x+y
Probably, I don't since dict is a blackbox and I have to check things first before use them.
People are free to write their own style guides that disagree with pep 8 (a point which is now made explicitly in the PEP).
Disclaimer: I don't try to stand for lambdas, I'm not using them everywhere in my code, but I'd like to know answer for the question "Why lambdas?". Currently, it is "Handy shorthand functions - use them free", but with new PEP-8 statement I really have to think like "Lambdas? Really, why?".
Use them for an anonymous function as an expression. All PEP 8 is now saying is that giving a lambda a name is to completely misunderstand what they're for. Cheers, Nick.
On Fri, Aug 2, 2013 at 1:10 PM, Nick Coghlan
Lambda was almost removed in Python 3.
Using `dict` to store lambdas:
op = { 'add': lambda x,y: x*y, 'mul': lambda x, y: x+y}
Shows the hack to bypass PEP8 guides. Do you like to see code above instead of:
add = lambda x,y: x*y mul = lambda x, y: x+y
Probably, I don't since dict is a blackbox and I have to check things first before use them.
People are free to write their own style guides that disagree with pep 8 (a point which is now made explicitly in the PEP).
Disclaimer: I don't try to stand for lambdas, I'm not using them everywhere in my code, but I'd like to know answer for the question "Why lambdas?". Currently, it is "Handy shorthand functions - use them free", but with new PEP-8 statement I really have to think like "Lambdas? Really, why?".
Use them for an anonymous function as an expression. All PEP 8 is now saying is that giving a lambda a name is to completely misunderstand what they're for.
Cheers, Nick.
Thanks for explanations, Nick, I'd got the point. -- ,,,^..^,,,
On Thu, Aug 1, 2013 at 3:36 PM, Terry Reedy
On 8/1/2013 11:03 AM, Alexander Shorin wrote:
...and, if so, why lambda's?(: Without backward compatibility point I see that they are getting "unofficially" deprecated and their usage is dishonoured.
Please stop both the top-posting and the FUD.
Top posting doesn't matter. The end.
On Thu, Aug 1, 2013 at 3:44 PM, Brian Curtin
On Thu, Aug 1, 2013 at 3:36 PM, Terry Reedy
wrote: On 8/1/2013 11:03 AM, Alexander Shorin wrote:
...and, if so, why lambda's?(: Without backward compatibility point I see that they are getting "unofficially" deprecated and their usage is dishonoured.
Please stop both the top-posting and the FUD.
Top posting doesn't matter.
The end.
Actually, quick expansion on this before moving along: if you're going to call someone out for top posting, you can't ignore the many high profile people who do it every time and single out the newcomer. That's why I said something. Sorry for the OT.
On Thu, 01 Aug 2013 16:53:16 +0200, Ronald Oussoren
On 1 Aug, 2013, at 16:48, Alexander Shorin
wrote: I understand this, but I'm a bit confused about fate of lambdas with such guideline since I see no more reasons to use them with p.9 statement: long lines, code duplicate, no mock and well tests etc. - all these problems could be solved with assigning lambda to some name, but now they are looks useless (or useful only for very trivial cases)
That sounds about right :-)
I don't understand the cases being mentioned in the question, but there are certainly places where lambdas are useful. The most obvious is as arguments to functions that expect functions as arguments. But yes, even in those cases if a lambda isn't fairly trivial, it probably shouldn't be a lambda. --David
Hi Alexander, On 02/08/13 00:48, Alexander Shorin wrote:
Hi Ronald,
I understand this, but I'm a bit confused about fate of lambdas with such guideline since I see no more reasons to use them with p.9 statement: long lines, code duplicate, no mock and well tests etc. - all these problems could be solved with assigning lambda to some name, but now they are looks useless (or useful only for very trivial cases)
Lambda is still useful for the reason lambda has always been useful: it is an expression, not a statement, so you can embed it directly where needed. # Preferred: sorted(data, key=lambda value: value['spam'].casefold()) # Allowed: def f(value): return value['spam'].casefold() sorted(data, key=f) # Prohibited: f = lambda value: value['spam'].casefold() sorted(data, key=f) # SyntaxError: sorted(data, key=def f(value): value['spam'].casefold()) -- Steven
Hi Steven,
On Thu, Aug 1, 2013 at 7:06 PM, Steven D'Aprano
Hi Alexander,
On 02/08/13 00:48, Alexander Shorin wrote:
Hi Ronald,
I understand this, but I'm a bit confused about fate of lambdas with such guideline since I see no more reasons to use them with p.9 statement: long lines, code duplicate, no mock and well tests etc. - all these problems could be solved with assigning lambda to some name, but now they are looks useless (or useful only for very trivial cases)
Lambda is still useful for the reason lambda has always been useful: it is an expression, not a statement, so you can embed it directly where needed.
# Preferred: sorted(data, key=lambda value: value['spam'].casefold())
# Allowed: def f(value): return value['spam'].casefold() sorted(data, key=f)
# Prohibited: f = lambda value: value['spam'].casefold() sorted(data, key=f)
# SyntaxError: sorted(data, key=def f(value): value['spam'].casefold())
The case: items = [[0, 'foo'], [3, 'baz'], [2, 'foo'], [1, 'bar']] Need to group by second item. Quite common task:
from itertools import groupby
for key, items in groupby(items, key=lambda i: i[1]): print(key, ':', list(items)) foo : [[0, 'foo']] baz : [[3, 'baz']] foo : [[2, 'foo']] bar : [[1, 'bar']]
oops, failed, we need to sort things first by this item and it looks we have to duplicate grouping function: fun = lambda i: i[1] for key, items in groupby(sorted(items, key=fun), key=fun): print(key, ':', list(items)) Ok, PEP suggests to use defs, so we adds 3 more lines (before and after def + return) to code: def fun(i): return i[1] for key, items in groupby(sorted(items, key=fun), key=fun): print(key, ':', list(items)) so that's the question: what is the rationale of this if lambdas successfully solves the problem with minimal amount of typing, code and thinking? I thought there should be only one way to do something, but this PEP-8 statement conflicts with PEP-20 one:
There should be one-- and preferably only one --obvious way to do it.
It's really not oblivious why lambdas couldn't be assignment to some name, especially in the light of fact that if they are been passed to some function as argument, they will be assignee to some name. -- ,,,^..^,,,
On Thu, Aug 1, 2013 at 5:58 PM, Alexander Shorin
fun = lambda i: i[1] for key, items in groupby(sorted(items, key=fun), key=fun): print(key, ':', list(items))
I'd do a direct translation to def here: def fun(i): return i[1] for key, items in groupby(sorted(items, key=fun), key=fun): print(key, ':', list(items)) ChrisA
Chris Angelico writes:
On Thu, Aug 1, 2013 at 5:58 PM, Alexander Shorin
wrote: fun = lambda i: i[1] for key, items in groupby(sorted(items, key=fun), key=fun): print(key, ':', list(items))
I'd do a direct translation to def here:
def fun(i): return i[1] for key, items in groupby(sorted(items, key=fun), key=fun): print(key, ':', list(items))
As long as it's about readability, why not make it readable? def second(pair): return pair[1] for key, items in groupby(sorted(items, key=second), key=second): print(key, ':', list(items)) I realize it's somewhat unfair (for several reasons) to compare that to Alexander's "fun = lambda i: i[1]", but I can't help feeling that in another sense it is fair.
* Stephen J. Turnbull wrote:
Chris Angelico writes:
On Thu, Aug 1, 2013 at 5:58 PM, Alexander Shorin
wrote: fun = lambda i: i[1] for key, items in groupby(sorted(items, key=fun), key=fun): print(key, ':', list(items))
I'd do a direct translation to def here:
def fun(i): return i[1] for key, items in groupby(sorted(items, key=fun), key=fun): print(key, ':', list(items))
As long as it's about readability, why not make it readable?
def second(pair): return pair[1] for key, items in groupby(sorted(items, key=second), key=second): print(key, ':', list(items))
I realize it's somewhat unfair (for several reasons) to compare that to Alexander's "fun = lambda i: i[1]", but I can't help feeling that in another sense it is fair.
Seems to run OT somewhat, but "second" is probably a bad name here. If the key changes, you have to rename it in several places (or worse, you DON'T rename it, and then the readability is gone). Usually I'm using a name with "key" in it - describing what it's for, not how it's done. The minimal distance to its usage is supporting that, too. nd -- "Das Verhalten von Gates hatte mir bewiesen, dass ich auf ihn und seine beiden Gefährten nicht zu zählen brauchte" -- Karl May, "Winnetou III" Im Westen was neues: http://pub.perlig.de/books.html#apache2
On Thu, Aug 1, 2013 at 12:58 PM, Alexander Shorin
Hi Steven,
On Thu, Aug 1, 2013 at 7:06 PM, Steven D'Aprano
wrote: Hi Alexander,
On 02/08/13 00:48, Alexander Shorin wrote:
Hi Ronald,
I understand this, but I'm a bit confused about fate of lambdas with such guideline since I see no more reasons to use them with p.9 statement: long lines, code duplicate, no mock and well tests etc. - all these problems could be solved with assigning lambda to some name, but now they are looks useless (or useful only for very trivial cases)
Lambda is still useful for the reason lambda has always been useful: it is an expression, not a statement, so you can embed it directly where needed.
# Preferred: sorted(data, key=lambda value: value['spam'].casefold())
# Allowed: def f(value): return value['spam'].casefold() sorted(data, key=f)
# Prohibited: f = lambda value: value['spam'].casefold() sorted(data, key=f)
# SyntaxError: sorted(data, key=def f(value): value['spam'].casefold())
The case:
items = [[0, 'foo'], [3, 'baz'], [2, 'foo'], [1, 'bar']]
Need to group by second item. Quite common task:
from itertools import groupby
for key, items in groupby(items, key=lambda i: i[1]): print(key, ':', list(items)) foo : [[0, 'foo']] baz : [[3, 'baz']] foo : [[2, 'foo']] bar : [[1, 'bar']]
oops, failed, we need to sort things first by this item and it looks we have to duplicate grouping function:
fun = lambda i: i[1] for key, items in groupby(sorted(items, key=fun), key=fun): print(key, ':', list(items))
Ok, PEP suggests to use defs, so we adds 3 more lines (before and after def + return) to code:
def fun(i): return i[1]
for key, items in groupby(sorted(items, key=fun), key=fun): print(key, ':', list(items))
so that's the question: what is the rationale of this if lambdas successfully solves the problem with minimal amount of typing, code and thinking? I thought there should be only one way to do something, but this PEP-8 statement conflicts with PEP-20 one:
There should be one-- and preferably only one --obvious way to do it.
It's really not oblivious why lambdas couldn't be assignment to some name, especially in the light of fact that if they are been passed to some function as argument, they will be assignee to some name.
Just because you can doesn't mean you should. This guideline is all about being explicit over implicit, not about saving typing. If you want to bind a function to a name then you should use a def to specify that fact; you also lose some things otherwise (e.g. __name__ is not set). Lambdas should be thought of one-off functions you write inline because it expresses the intent of the code just as well. Assigning a lambda to a variable is in no way more beneficial compared to using def and thus this guideline suggesting you use def to make it at least as clear, if not more and to gain benefits such as __name__ being set (which helps with debugging, etc.).
Steven D'Aprano wrote:
Lambda is still useful for the reason lambda has always been useful: it is an expression, not a statement, so you can embed it directly where needed.
are there some possibilities to change def to an expression? do I need to wait 'till python9k? yes, this brings to the possibility to write something like foo = def bar(): pass but at least should let the lambda to die in peace... -- ZeD
On 8/1/2013 10:48 AM, Alexander Shorin wrote:
I understand this, but I'm a bit confused about fate of lambdas with such guideline since I see no more reasons to use them with p.9 statement: long lines, code duplicate, no mock and well tests etc. - all these problems could be solved with assigning lambda to some name, but now they are looks useless (or useful only for very trivial cases)
I do not understand most of that, but... The guideline is not meant to cover passing a function by parameter name. mylist.sort(key=lambda x: x[0]) is still ok. Does "Always use a def statement instead of assigning a lambda expression to a name." need 'in an assignment statement' added? -- Terry Jan Reedy
On 8/1/2013 10:34 AM, Alexander Shorin wrote:
Hi Nick,
On Thu, Aug 1, 2013 at 4:44 PM, Nick Coghlan
wrote: 9. Explicit guideline not to assign lambdas to names (use def, that's what it's for)
Even for propose to fit chars-per-line limit
def f(x): return 2*x f = lambda x: 2*x Three spaces is seldom a crucial difference. If the expression is so long it go past the limit (whatever we decide it is), it can be wrapped.
and/or to remove duplicates (especially for sorted groupby case)?
I do not understand this. -- Terry Jan Reedy
On Thu, Aug 1, 2013 at 4:29 PM, Terry Reedy
def f(x): return 2*x f = lambda x: 2*x
Am I the only one who finds the second line above much more readable than the first? The def statement is not intended to be written in one line. The readability suffers because the argument is separated from the value expression by return keyword. When def statement is written traditionally: def f(x): return 2*x It is easy to run the eyes over the right margin and recognize a function that in a math paper would be written as "f: x -> 2 x". Same is true about lambda expression. While C# syntax "f = (x => 2*x)" is probably closest to mathematical notation, "f = lambda x: 2*x" is close enough. One can mentally focus on the "x: 2*x" part and ignore the rest.
On 02/08/13 06:52, Alexander Belopolsky wrote:
On Thu, Aug 1, 2013 at 4:29 PM, Terry Reedy
wrote: def f(x): return 2*x f = lambda x: 2*x
Am I the only one who finds the second line above much more readable than the first? The def statement is not intended to be written in one line. The readability suffers because the argument is separated from the value expression by return keyword.
You are not the only one. I will continue to write "f = lambda ..." at the interactive interpreter without shame, although I rarely (never?) use it in code. -- Steven
On 01/08/13 22:44, Nick Coghlan wrote:
With feedback from Guido, Barry, Raymond and others, I have updated PEP 8 to better describe our current development practices. It started as an update to describe the different between public and internal interfaces and to advise against using wildcard imports, but became substantially more :)
Before this entire thread be buried in a mountain of controversy over the 79-99 line length issue, let me say thanks Nick and the others for your work on this. -- Steven
On Thu, Aug 1, 2013 at 8:44 AM, Nick Coghlan
9. Explicit guideline not to assign lambdas to names (use def, that's what it's for)
Would you consider changing the formatting in the recommended example from def f(x): return 2*x to def f(x): return 2*x ? What is the modern view on single-line def? The "Other Recommendations" section allows but discourages single-line if/for/while, but is silent about def.
On 4 Aug 2013 11:30, "Alexander Belopolsky"
On Thu, Aug 1, 2013 at 8:44 AM, Nick Coghlan
wrote: 9. Explicit guideline not to assign lambdas to names (use def, that's what it's for)
Would you consider changing the formatting in the recommended example from
def f(x): return 2*x
to
def f(x): return 2*x
?
I consider a single line def acceptable when replacing an equivalent lambda. Restricting it to a single line makes it solely about the spelling of the assignment operation, without any vertical whitespace considerations. Cheers, Nick.
What is the modern view on single-line def? The "Other Recommendations"
section allows but discourages single-line if/for/while, but is silent about def.
participants (18)
-
Alexander Belopolsky
-
Alexander Shorin
-
André Malo
-
Antoine Pitrou
-
Barry Warsaw
-
Brett Cannon
-
Brian Curtin
-
Chris Angelico
-
Fred Drake
-
LD 'Gus' Landis
-
Nick Coghlan
-
R. David Murray
-
Ronald Oussoren
-
Skip Montanaro
-
Stephen J. Turnbull
-
Steven D'Aprano
-
Terry Reedy
-
Vito De Tullio