Live data from Hacker News

Anti-Patterns in Python Programming

lignos.org

111–120 of 242 posts

Re: Anti-Patterns in Python Programming

#111
post #82

Earlier quoted context omitted.

Depends on how you want to program: imperative vs functional. Personally I think list comprehensions are the most beautiful part of Python, though sometimes I use map() when I'm trying to be explicitly functional (I realize it's allegedly slower, etc). Generally I think list comprehensions are cleaner and allow you to write purer functions with fewer mutable variables. I disagree that deeply nested for loops are nece…

Map is not allegedly slower, it is demonstrably slower. $ python -mtimeit -s'nums=range(10)' 'map(lambda i: i + 3, nums)' 1000000 loops, best of 3: 1.61 usec per loop $ python -mtimeit -s'nums=range(10)' '[i + 3 for i in nums]' 1000000 loops, best of 3: 0.722 usec per loop Function calls have overhead in python, list comprehensions are implemented knowing this fact and avoiding it so the heavy lifting ultimately happ…

Fair enough. I said "allegedly" because I had never personally measured the performance difference.

Even though you could construe map as "half as fast" (or twice as slow) as the equivalent comprehension, I don't see a difference of ~1 usec making any difference in my code thus far. Good to know, though.

Re: Anti-Patterns in Python Programming

#112
post #52
post #3

The more frequent and dangerous pitfalls are, in my humble opinion: - Bare except: statements (that catches everything , even Ctrl-C) - Mutables as default function/method arguments - Wildcard imports!

Agreed on all counts. However I do find myself using mutables as default arguments sometimes because the generated documentation is clearer. For example, this is a real method in one of my projects: def listen(self, address, ssl=False, ssl_args={}): pass I like the way this turns up in the docs because it's immediately clear that ssl_args needs to be a dict. Otherwise I have to describe it in words.

[deleted]

Re: Anti-Patterns in Python Programming

#113

I can't think of a single case where using sentinel values is necessary or appropriate in Python. Generally speaking, one should just return from within the loop.

I get what you're saying, but even when sentinels are used inside a function, returning a -1 to the caller seems like a pretty bad API. It's OK to raise ValueError! I had thought the idiomatic sentinel value was an instance of object() you could is against, anyway.

Re: Anti-Patterns in Python Programming

#114
post #94

Earlier quoted context omitted.

It has something to do with mutability, because if an object is immutable, the behavior of Python matches what the naive developer expects. It's only mutable objects that break those expectations. Don't even get into unexpected behavior in classes: In [1]: class A(object): ...: l = [] ...: In [2]: a, b = A(), A() In [3]: a.l.append("Something") In [4]: a.l Out[4]: ['Something'] In [5]: b.l Out[5]: ['Something'] In [6…

I'm sorry, but I don't understand why you would think this as unexpected behaviour? For the class A, the list l is a class-level attribute, hence it can be referred via either a or b objects, but for class B, after initialisation, l is an object attribute, so it is different for both c and d.

It's not the concept that can be confusing, it's the syntax python chose.

In most of the languages I'm familiar with, there are very clear syntax differences when working with class attributes. For example, in many languages class attributes have to be accessed via the class name instead of from an instance of the class making it clear to the programmer they are working with a class attribute, e.g. MyClass.myClassVariable not myInstance.myClassVariable. Additionally, the way you define class attributes in python is the way you define instance attributes in many languages, which just adds to the confusion. e.g. in Java or C# you can define class variables directly in the class body, but an explicit 'static' keyword is needed, undecorated definitions are assumed to be instance variables.

Finally, I think the definition of class B above is a little more nuanced, class B has both a class attribute named l AND an instance attribute named l.

B.l == None and B().l == []

Re: Anti-Patterns in Python Programming

#115

I can't think of a single case where using sentinel values is necessary or appropriate in Python. Generally speaking, one should just return from within the loop.

I get what you're saying, but even when sentinels are used inside a function, returning a -1 to the caller seems like a pretty bad API. It's OK to raise ValueError ! I had thought the idiomatic sentinel value was an instance of object() you could is against, anyway.

I agree - especially when you're returning a list index, since `[-1]` is a valid index in Python.

Re: Anti-Patterns in Python Programming

#116
post #75
post #63

Earlier quoted context omitted.

Well, that's throwing people implementing subclasses under the bus, IMO. Why not just add @param annotations in your docstrings instead?

> Well, that's throwing people implementing subclasses under the bus, IMO. If they need to touch this argument in an overridden method and they don't know what they are doing, then yes. > Why not just add @param annotations in your docstrings instead? I'm using Sphinx and it renders them separately. I want the empty dict to show up in the function signature.

A single cryptic bug due to this practice will more than negate the minor doc readability benefits you get from that. And there will likely be many more than one cryptic bug.

There are other ways to emphasize it ought to be a dict/mappable. Change its name to be suffixed as "_dict", for example?

Re: Anti-Patterns in Python Programming

#117

Mmm... you should always use 'if x is not None:' imo. It's very common for libraries to make values evaluate to False, and very easy to get bugs if you just lazily test with 'if x'. Sqlalchemy springs to mind immediately as one of the common ones where using any() and if x: is a reeeeeallly bad idea; there are plenty of others. I'm pretty skpetical about modifying your coding behavior based on what libraries you happ…

It depends.

If you're checking to see if that value is None, then yes - you should check that.

If you're merely checking if the value is truthy, then using "if x:" is completely legitimate.

Re: Anti-Patterns in Python Programming

#118
post #114

Earlier quoted context omitted.

I'm sorry, but I don't understand why you would think this as unexpected behaviour? For the class A, the list l is a class-level attribute, hence it can be referred via either a or b objects, but for class B, after initialisation, l is an object attribute, so it is different for both c and d.

It's not the concept that can be confusing, it's the syntax python chose. In most of the languages I'm familiar with, there are very clear syntax differences when working with class attributes. For example, in many languages class attributes have to be accessed via the class name instead of from an instance of the class making it clear to the programmer they are working with a class attribute, e.g. MyClass.myClassVar…

Ah, gotcha!

It's been a while since I've done major OOP coding in any language other than Python, so I'm a little rusty. The issues you raise are perfectly legitimate and would be understandably confusing to newcomers to the language. :)

Re: Anti-Patterns in Python Programming

#119
post #24

Earlier quoted context omitted.

Why even use a list here? Tuples are for immutable/constant data. a_tuple_of_words = ("my", "tuple", "of", "words") or a_tuple_of_words = "my", "tuple", "of", "words"

...because it's a list? Tuples were supposed to have a structure (at least that's what all the rest of the world thinks of them), so iterating through combination of apples, cars and languages makes no sense whatsoever. But yes, Python misses entirely the point of tuples, treating them as read-only lists. http://dozzie.jogger.pl/2014/04/11/python-tuples-the-useless...

Python tuples are used in both ways.

Even in Haskell, though, people often write all kinds of type-class magic to allow "iterating" over a tuple. For example, a Binary instance over a tuple wants to call "put" on each element.

Haskell's (Oleg's) HList is basically a tuple with iteration/list-like operations.

Post reply on HN