Python Worst Practices

Chris Angelico rosuav at gmail.com
Thu Feb 26 08:12:57 EST 2015


On Thu, Feb 26, 2015 at 11:26 PM, Steven D'Aprano
<steve+comp.lang.python at 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



More information about the Python-list mailing list