Live data from Hacker News

Python Best Practice Patterns

stevenloria.com

31–40 of 97 posts

Re: Python Best Practice Patterns

#31
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…

What is your reasoning for not making methods chainable?

http://en.wikipedia.org/wiki/Fluent_interface#Java

Re: Python Best Practice Patterns

#32
post #31
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…

What is your reasoning for not making methods chainable? http://en.wikipedia.org/wiki/Fluent_interface#Java

Chainable mutating methods are not idiomatic Python; returning None is idiomatic for mutating methods. ISTR that the reasons here regard readability and clearly distinguishing mutations from queries, but in any case if you don't follow the idiom in libraries you create, they won't behave like Python's builtins and standard library, which, whatever you think about chaining on its own, will cause some context switching for most Python users when trying to work with it, increasing the cognitive load.

Re: Python Best Practice Patterns

#33

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.

Thanks! I've wondered about this.. I do like the parens better, and it looks like PEP-8 agrees with you: http://legacy.python.org/dev/peps/pep-0008/#maximum-line-len...

Re: Python Best Practice Patterns

#35
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…

For certain use-cases (like constructing queries for an ORM) or other things where you're effectively passing around curried ideas to eventually be executed, I think cascading methods is a huge win.

What you are referring to is a design pattern called fluent interfaces[1]. They do make for very usable APIs when used to represent pipelines and filters. They are also used heavily in creating domain specific language features. In your SQL example it works very well such as in SQLAlchemy. But in that example, the chained methods are building a query as opposed to mutating the actual data. Splitting hairs.

[1]http://en.m.wikipedia.org/wiki/Fluent_interface

Re: Python Best Practice Patterns

#36
post #31

Earlier quoted context omitted.

What is your reasoning for not making methods chainable? http://en.wikipedia.org/wiki/Fluent_interface#Java

Chainable mutating methods are not idiomatic Python; returning None is idiomatic for mutating methods. ISTR that the reasons here regard readability and clearly distinguishing mutations from queries, but in any case if you don't follow the idiom in libraries you create, they won't behave like Python's builtins and standard library, which, whatever you think about chaining on its own, will cause some context switching…

The builtins are broken, that is why there are new builtins liked `sorted()`, list.sort() returning None is not an improvement. The standard libraries are a _mess_, there is absolutely know cohesion in their api design, or even naming conventions (go peruse the standard lib). Much of what is Pythonic is someones opinion on how a nanny-language should behave.

At this point I think calling something idiomatic or Pythonic is a thought terminating statement. I need to see refutation.

Re: Python Best Practice Patterns

#37
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…

Showed this to a senior dev at work and he pointed out another (subtle) error

    for each in enumerate(items):
        if each.match(self):
            # This fails because enumerate yields an (index, value) tuple.
            # Match isn't a function defined on tuples.

Re: Python Best Practice Patterns

#38
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 I'm curious, as someone who uses this pattern quite a bit, how would you improve on this?

Just speculating here, but a func that just ends without returning, effectively returns None, so that idiom may be considered redundant. IMHO, it's often worth the additional clarity to be redundant in this way.

Re: Python Best Practice Patterns

#39

Earlier quoted context omitted.

> * the last one (`return None`) make me very dubious I'm curious, as someone who uses this pattern quite a bit, how would you improve on this?

Just speculating here, but a func that just ends without returning, effectively returns None, so that idiom may be considered redundant. IMHO, it's often worth the additional clarity to be redundant in this way.

    In [1]: def foo(): pass
    
    In [2]: foo() is None
    Out[2]: True

Re: Python Best Practice Patterns

#40

Agree with all of these but two. The first is the example of doing: class Foo(object): highlight = reverse No, that is not clearer. Now I have no idea what this method does. Making it explicit requires more keystrokes, but allows you to properly document the method. Also, when I run help(Foo.highlight) I won't get the generic documentation for `reverse`. Second, using `each` for a generic iteration variable. This is…

The whole "use __iter__ whenever you can" thing is dubious too. It may be fine sometimes but the example is poorly chosen. If the department gains a name and a manager, using __iter__ makes much less sense. And now you also need to implement __len__ if you want to count your employees, etc.
Post reply on HN