Live data from Hacker News

Python Best Practice Patterns

stevenloria.com

41–50 of 97 posts

Re: Python Best Practice Patterns

#41
post #30
post #3

And the most important pattern: http://stackoverflow.com/questions/1275646/python-3-and-stat...

except no tools use it, yet . I would absolutely love a version of shedskin that moved to Python3 syntax and used optional typing.

PyCharm will read simple type annotations like

  def get_error_message(error_code: int) -> string:
      ...
and use them for autocompletion hints and type warnings.

Re: Python Best Practice Patterns

#42

Earlier quoted context omitted.

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

I was speculating about what the original complainer meant, not about what python does... b^)

Re: Python Best Practice Patterns

#43
post #35

Earlier quoted context omitted.

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:/…

> Splitting hairs.

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

Re: Python Best Practice Patterns

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

> * if a method does not use the object's state (no `self` usage) make it a `class-` or `staticmethod`.

Is this really true?

Re: Python Best Practice Patterns

#46

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…

`highlight = reverse` also flies in the face of TOOWTDI (from PEP 20).

Which is a shame, because this means that convenience methods that Ruby has, e.g. ary.first → ary[0], ary.compact → ary.reject{|x| x.nil? }, ary.map → ary.collect are pruned out of the stdlib and frowned on in contributed libraries. This chilling effect that descends from PEP20 is one of the worse aspects of Python.

They increase readability and should be encouraged. Even if ary.last is one more character, it uses less of my brain to read than ary[-1]. ary.map might be more readable if other code uses ary.reduce, while ary.collect is more readable if other code uses ary.inject, ary.detect, etc.

The OP gave a perfect example with this---in an event handler for a drag operation within an editor, I'd rather communicate that text is being .highlight()-ed, even if the underlying view methods are reversing the pixels. If I used .reverse(), it might confuse a coder into thinking the text itself is being reversed when I drag.

Perhaps if more Pythonistas consider this a "best practice," it will swing favor for amending the Zen. But I wouldn't bet on it.

Also, you're incorrect about help(). help(Foo.highlight) will provide the docstring for Foo.reverse if Foo.highlight = Foo.reverse.

Re: Python Best Practice Patterns

#47
post #35

Earlier quoted context omitted.

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:/…

> 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.

Re: Python Best Practice Patterns

#48
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?

I do this too. I dislike when functions in languages don't explicitly return something even if that something is nothing.

Re: Python Best Practice Patterns

#49
post #11
post #7

I'm skeptical about the last one return None

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.
Post reply on HN