Live data from Hacker News

Python Best Practice Patterns

stevenloria.com

71–80 of 97 posts

Re: Python Best Practice Patterns

#71
post #49
post #11

Earlier quoted context omitted.

I saw this code yesterday: def is_file_for(is_nagyker, type): if type == KIS_ES_NAGYKER: return True elif type == KISKER and not is_nagyker: return True elif type == NAGYKER and is_nagyker: return True At the first glance, I thought it always return True. Would have been more clear an explicit return False at the end!

May I suggest `any` here? def is_file_for(is_nagyker, type): return any([ type == KIS_ES_NAGYKER, type == KISKER and not is_nagyker, type == NAGYKER and is_nagyker]) I know unsolicited code improvements from strangers isn't the coolest thing in the world, but `any` (and `all`) can really improve clarity for stuff like this. I know I use them quite a bit.

I saw that used in the article too - not something I'd thought to do myself. Thanks for pointing it out, I find it really readable and I know there are places I could use this.

Re: Python Best Practice Patterns

#72

Earlier quoted context omitted.

Seems rude to return None instead of False for an is_. I think I would have written: def is_file_for(is_nagyker, type): return type == KIS_ES_NAGYKER or \ (type == KISKER and not is_nagyker) or \ (type == NAGYKER and is_nagyker)

As another change, it is recommended to avoid explicit line continuations by using parentheses instead. def is_file_for(is_nagyker, type): return ((type == KIS_ES_NAGYKER) or (type == KISKER and not is_nagyker) or (type == NAGYKER and is_nagyker)) This way, it doesn't break if there is extra whitespace at the end of the line.

As yet another change, PEP8 recommends placing comparison operators (and dots, when method chaining) at the beginning of each line to make things a little clearer.

    def is_file_for(is_nagyker, type):
         return ((type == KIS_ES_NAGYKER)
                 or (type == KISKER and not is_nagyker)
                 or (type == NAGYKER and is_nagyker))

Re: Python Best Practice Patterns

#73
post #47

Earlier quoted context omitted.

> Splitting hairs. Severely, since what you're doing is mutating the actual state-data of the query object.

In the case of SQLAlchemy you are not. The cascading methods on query objects create new query objects as it should be. Mutating objects with cascading methods is horrible API design as it suggests immutability where there is none.

the API in some ways comes from that of Hibernate, which does actually mutate in place (see http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html...). I felt that keeping the existing object un-mutated is a lot more intuitive. I think the names that you choose for the methods do make a difference, e.g. Hibernate is saying "add()" which for whatever reason seems to imply "mutation" to me, not sure why.

Re: Python Best Practice Patterns

#77
post #9

Several of those patterns are incomplete or frowned upon: * if a method does not use the object's state (no `self` usage) make it a `class-` or `staticmethod`. * Some magic methods are presented. There's more to them[0]. * one should not write `class MyClass:` but `class MyClass(object):` (new style class[1]) * the last one (`return None`) make me very dubious * Cascading methods: that's a big no . The idiom is that…

> * the last one (`return None`) make me very dubious

simply `return` would be enough

Re: Python Best Practice Patterns

#78

Earlier quoted context omitted.

As another change, it is recommended to avoid explicit line continuations by using parentheses instead. def is_file_for(is_nagyker, type): return ((type == KIS_ES_NAGYKER) or (type == KISKER and not is_nagyker) or (type == NAGYKER and is_nagyker)) This way, it doesn't break if there is extra whitespace at the end of the line.

As yet another change, PEP8 recommends placing comparison operators (and dots, when method chaining) at the beginning of each line to make things a little clearer. def is_file_for(is_nagyker, type): return ((type == KIS_ES_NAGYKER) or (type == KISKER and not is_nagyker) or (type == NAGYKER and is_nagyker))

See, I don't find that clearer; quite the reverse. With trailing 'or' the type variable is nicely lined up, and the pattern matching that is going on is a lot clearer to my eye. With things misaligned, I have to much more carefully parse the text to see what is going on. I sometimes even do something like this (probably overkill in this example, but my aim is to illustrate a concept, not to bicker about the best expression of that particular statement):

   return (
    (type == KIS_ES_NAGYKER                   ) or
    (type == KISKER         and not is_nagyker) or
    (type == NAGYKER        and     is_nagyker))

Re: Python Best Practice Patterns

#79
post #16

Author here. Must give credit where it's due: These patterns come from a talk by Vladimir Keleshev, author of docopt and excellent Pythonista. These are NOT my original work.

You couldn't say anything to motivates me more about reading the linked article. docopt is a gem ;)

Re: Python Best Practice Patterns

#80

Having gone through a couple thousand lines of Javascript that adhered to the "keep methods small", I call bollocks on that. Make methods as big as they need to be. function doFooOnList(l) { for (var i=0; i gets old, very quickly. After designing and building code for 20+ years, I can comfortably say that there are no arbitrary rules of software design, and some of the worst code I've seen has been a result of follow…

some of the worst code I've seen has been a result of following "best practices" instead of thinking for oneself.

Very very true. This phrase suggests there is no better way to do something, and that it should always be used because it is "best", and the dogmatic application of rules replaces actual thought and understanding. I am not against a "recommendation" or "suggestion", but to call it "best practice" is cargo-cult-like.

Post reply on HN