Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #86439 > unrolled thread

Python Worst Practices

Started byMark Lawrence <breamoreboy@yahoo.co.uk>
First post2015-02-25 20:45 +0000
Last post2015-02-27 00:37 +1100
Articles 8 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  Python Worst Practices Mark Lawrence <breamoreboy@yahoo.co.uk> - 2015-02-25 20:45 +0000
    Re: Python Worst Practices Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-02-26 10:54 +1100
      Re: Python Worst Practices Chris Angelico <rosuav@gmail.com> - 2015-02-26 11:26 +1100
        Re: Python Worst Practices Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2015-02-26 23:26 +1100
          Re: Python Worst Practices Chris Angelico <rosuav@gmail.com> - 2015-02-27 00:12 +1100
    Re: Python Worst Practices wxjmfauth@gmail.com - 2015-02-25 22:46 -0800
    Re: Python Worst Practices m <mvoicem@gmail.com> - 2015-02-26 14:12 +0100
      Re: Python Worst Practices Chris Angelico <rosuav@gmail.com> - 2015-02-27 00:37 +1100

#86439 — Python Worst Practices

FromMark Lawrence <breamoreboy@yahoo.co.uk>
Date2015-02-25 20:45 +0000
SubjectPython Worst Practices
Message-ID<mailman.19215.1424897186.18130.python-list@python.org>
http://www.slideshare.net/pydanny/python-worst-practices

Any that should be added to this list?  Any that be removed as not that bad?

-- 
My fellow Pythonistas, ask not what our language can do for you, ask
what you can do for our language.

Mark Lawrence

[toc] | [next] | [standalone]


#86450

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-02-26 10:54 +1100
Message-ID<54ee60af$0$13001$c3e8da3$5496439d@news.astraweb.com>
In reply to#86439
Mark Lawrence wrote:

> http://www.slideshare.net/pydanny/python-worst-practices
> 
> Any that should be added to this list?  Any that be removed as not that
> bad?


I have no idea about Python worst practices, but I think using some sort of
Powerpoint slide is surely one of the worst practices in general. In my
browser, I see the title "Python Worst Practices". There's a Next Slide
button, but clicking it does nothing.

Down below, there is what appears to be a transcript, but it is full of
extraneous and unnecessary fluff (nearly every line has a leading "Daniel
Greenfeld @pydanny") and the formatting is destroyed.


Worst practices:

- Using assert for error checking, instead of explicit tests.

- Overuse of regexes. If the only tool you have is the regex 
  hammer, everything looks like a nail.

- Underuse of regexes: failing to use a regex when one is called 
  for is not quite as bad as the regex hammer, but still.

- Python is not Java.

http://dirtsimple.org/2004/12/python-is-not-java.html‎
http://dirtsimple.org/2004/12/java-is-not-python-either.html


Most worst practices are independent of the language. Regardless of whether
they are writing Python, C or Ocaml, too many programmers make these deadly
programming sins:

- Too much coupling. Possibly the Mother Of All Sins, many other
  sins are variations of this: spaghetti code, ravioli code, global 
  variables, etc.

- Premature optimization. Which usually means, optimizing without
  measurement. If you just *assume* this code is "faster", chances
  are excellent that it is actually slower.

- Overuse of 1-character or excessively generic variable names.

- The other extreme: extremely_long_variable_names_for_no_good_reason.

- Variable names (including functions and classes!) that aren't
  self-explanatory.

- Misusing Hungarian notation. Or failing to use it when appropriate.

http://www.joelonsoftware.com/articles/Wrong.html

- Violating the Rule of Demeter: don't talk to the dog's leg, talk to 
  the dog. Or another way to put it: don't let the paper boy reach
  into your pocket for money.


And very possibly the worst practice of all:

- Failing to understand when it is, and isn't, appropriate to break
  the rules and do what would otherwise be a bad practice.





-- 
Steven

[toc] | [prev] | [next] | [standalone]


#86454

FromChris Angelico <rosuav@gmail.com>
Date2015-02-26 11:26 +1100
Message-ID<mailman.19226.1424910410.18130.python-list@python.org>
In reply to#86450
On Thu, Feb 26, 2015 at 10:54 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> - Violating the Rule of Demeter: don't talk to the dog's leg, talk to
>   the dog. Or another way to put it: don't let the paper boy reach
>   into your pocket for money.

I'd call that code smell, rather than an automatic worst practice. Suppose this:

class Shelf:
    def __init__(self):
        self.items = [] # Empty shelf

bookshelf = Shelf()
bookshelf.items.append(book)

To enforce Demeter, you'd have to add a bunch of methods to the Shelf
whose sole purpose is to pass word along to the items list. Sure, it
makes some design sense to say "Add this book to the shelf" rather
than "Add this book to the items on the shelf", but all those lines of
code are potential bugs, and if you have to reimplement huge slabs of
functionality, that too is code smell. So there are times when it's
correct to reach into another object.

But the times to use two dots are much rarer than the times to use one
dot (the paper boy shouldn't reach into your pocket for money, but
ThinkGeek has your credit card number on file so you can order more
conveniently), and I can't think of any example off-hand where you
would want more than three dots.

ChrisA

[toc] | [prev] | [next] | [standalone]


#86494

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2015-02-26 23:26 +1100
Message-ID<54ef10e8$0$12984$c3e8da3$5496439d@news.astraweb.com>
In reply to#86454
Chris Angelico wrote:

> On Thu, Feb 26, 2015 at 10:54 AM, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> wrote:
>> - Violating the Rule of Demeter: don't talk to the dog's leg, talk to
>>   the dog. Or another way to put it: don't let the paper boy reach
>>   into your pocket for money.
> 
> I'd call that code smell, rather than an automatic worst practice.


Well, I did end my post with:


And very possibly the worst practice of all:

- Failing to understand when it is, and isn't, appropriate to break
  the rules and do what would otherwise be a bad practice.


:-)


> Suppose this:
> 
> class Shelf:
>     def __init__(self):
>         self.items = [] # Empty shelf
> 
> bookshelf = Shelf()
> bookshelf.items.append(book)
> 
> To enforce Demeter, you'd have to add a bunch of methods to the Shelf
> whose sole purpose is to pass word along to the items list. Sure, it
> makes some design sense to say "Add this book to the shelf" rather
> than "Add this book to the items on the shelf", but all those lines of
> code are potential bugs, and if you have to reimplement huge slabs of
> functionality, that too is code smell. So there are times when it's
> correct to reach into another object.

Yes, well this comes down to the question of encapsulation and
information-hiding. The advantage of exposing the list of items to the
public is that anyone can add or remove items, sort them, reverse them,
etc. The disadvantage is that you are now committed to keeping that list as
part of the public API and you can't easily change the implementation.

In this specific example, I'd probably keep the list as part of the Shelf
API, although I'd be tempted to make self.items a read-only property. That
will allow you to call list mutator methods, but prevent you from doing
something silly like:

bookshelf.items = 23


> But the times to use two dots are much rarer than the times to use one
> dot (the paper boy shouldn't reach into your pocket for money, but
> ThinkGeek has your credit card number on file so you can order more
> conveniently), and I can't think of any example off-hand where you
> would want more than three dots.

The Law of Demeter is not really about counting dots. Ruby encourages
chaining methods. Python doesn't, since built-ins typically don't return
self. But in your own classes, you can have methods return self so you can
chain them like this:

mylist.append(spam).insert(1, eggs).append(cheese).sort().index(ham)

Five dots or not, this is not a violation of Demeter. Likewise for long
package names:

from mylibrary.audiovisual.image.jpeg import Handler


The Law of Demeter is more about information hiding. Clearly you don't hide
*public* attributes of your class, otherwise they aren't public, so it's
perfectly acceptable to say:

myshelf.items.append(spam).insert(1, eggs).append(cheese).sort().index(ham)

if items is public. But if the Shelf designer decides that the user
shouldn't know anything about how the shelf stores its items, then the
*first* dot violates the Law of Demeter.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#86497

FromChris Angelico <rosuav@gmail.com>
Date2015-02-27 00:12 +1100
Message-ID<mailman.19254.1424956384.18130.python-list@python.org>
In reply to#86494
On Thu, Feb 26, 2015 at 11:26 PM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> Chris Angelico wrote:
>
>> But the times to use two dots are much rarer than the times to use one
>> dot (the paper boy shouldn't reach into your pocket for money, but
>> ThinkGeek has your credit card number on file so you can order more
>> conveniently), and I can't think of any example off-hand where you
>> would want more than three dots.
>
> The Law of Demeter is not really about counting dots. Ruby encourages
> chaining methods. Python doesn't, since built-ins typically don't return
> self. But in your own classes, you can have methods return self so you can
> chain them like this:
>
> mylist.append(spam).insert(1, eggs).append(cheese).sort().index(ham)
>
> Five dots or not, this is not a violation of Demeter. Likewise for long
> package names:
>
> from mylibrary.audiovisual.image.jpeg import Handler

Yes, there are other places where you have lots of dots... I'm talking
about the "rule of thumb" shorthand for describing the Law of Demeter,
which is that you shouldn't have more than one dot before your method
call. The chaining isn't that, because each one is a separate entity;
but if you say "fred.house.bookshelf.items.append(book)", you're
reaching in far too deep - you should be giving Fred the book to place
on his own shelf. That's the only way where "counting dots" is a valid
shorthand. It's mentioned in the Wikipedia article for the law:

https://en.wikipedia.org/wiki/Law_of_Demeter#In_object-oriented_programming

Can you offer a less ambiguous way to describe Demeter violations? By
the "counting dots" style, Demeter demands one, I would be happy with
two, and three or more strongly suggests a flawed API or overly-tight
coupling - with the exception that module references don't get counted
("import os; os.path.append(p)" is one dot, because there's no point
having an "os.add_path()" method). In some languages, those module
references would be notated differently (os::path.append(p)), so
simply counting dots would be closer to accurate. Is there a better
Python description?

ChrisA

[toc] | [prev] | [next] | [standalone]


#86479

Fromwxjmfauth@gmail.com
Date2015-02-25 22:46 -0800
Message-ID<646615ef-d3cf-427a-94e7-e8b353c9bb53@googlegroups.com>
In reply to#86439
Le mercredi 25 février 2015 21:46:42 UTC+1, Mark Lawrence a écrit :
> http://www.slideshare.net/pydanny/python-worst-practices
> 
> Any that should be added to this list?  Any that be removed as not that bad?
> 
> -- 
> My fellow Pythonistas, ask not what our language can do for you, ask
> what you can do for our language.


I searched for a non ascii char.
I did not find one [0, 61] slides.

jmf

[toc] | [prev] | [next] | [standalone]


#86496

Fromm <mvoicem@gmail.com>
Date2015-02-26 14:12 +0100
Message-ID<54ef1bb8$0$2175$65785112@news.neostrada.pl>
In reply to#86439
W dniu 25.02.2015 21:45, Mark Lawrence pisze:
> http://www.slideshare.net/pydanny/python-worst-practices
>
> Any that should be added to this list?  Any that be removed as not that bad?
>


I disagree with slide 16. If I wanted to use long variable names, I 
would still code in Java.

regards

m.

[toc] | [prev] | [next] | [standalone]


#86500

FromChris Angelico <rosuav@gmail.com>
Date2015-02-27 00:37 +1100
Message-ID<mailman.19256.1424957869.18130.python-list@python.org>
In reply to#86496
On Fri, Feb 27, 2015 at 12:12 AM, m <mvoicem@gmail.com> wrote:
> W dniu 25.02.2015 21:45, Mark Lawrence pisze:
>>
>> http://www.slideshare.net/pydanny/python-worst-practices
>>
>> Any that should be added to this list?  Any that be removed as not that
>> bad?
>>
>
>
> I disagree with slide 16. If I wanted to use long variable names, I would
> still code in Java.

Clearly you aren't bothered by ambiguities, given that your name is
"m". You're lower-case m, and the James Bond character is upper-case
M... yeah, this isn't going to be a problem, with seven billion people
on the planet!

In case it's not obvious from slide 17, the author is advocating
neither the ridiculously short, nor the ridiculously long. This is a
topic that you could go into great detail on, but a general rule of
thumb is that short names go with short-lived variables, and longer
names go with large-scope variables. [1] So your function names
shouldn't be single letters, but your loop counters can and should be
short:

def discard_all_spam():
    for msg in self.messages:
        if msg.is_spam(): ms.discard()

And of course, the use of "i" as an integer loop index dates back so
far and is so well known that you don't need anything else:

def get_password():
    for i in range(4):
        if i: print("%d wrong tries...")
        s = input("What's the password? ")
        if validate_password(s): return s
    print("Too many wrong tries, go away.")

This isn't Java coding.

ChrisA

[1] Yes, Python doesn't have variables per se. But how else am I
supposed to differentiate between the name and the concept of a name
binding?

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web