Failing to use join is a big one. I have seen countless instances of people writing the logic to output commas in between items (like for CSV export) that they want to concatenate into a string. header_line = ','.join( header for header in headers ) csv_line = ','.join( str(dataset[key]) for key in dataset.keys() ) Example for a case of a dictionary mapping a string to a bunch of numbers.
Proper Python would use the csv module for this operation, as your CSV export would break if `header` or `dataset[key]` contains a comma.
Anti-Patterns in Python Programming
191–200 of 242 posts
Re: Anti-Patterns in Python Programming
#192Earlier 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…
> if an object is immutable, the behavior of Python matches what the naive developer expects If the object was immutable then append wouldn't work. That's hardly matching expectations.
Re: Anti-Patterns in Python Programming
#193Failing to use join is a big one. I have seen countless instances of people writing the logic to output commas in between items (like for CSV export) that they want to concatenate into a string. header_line = ','.join( header for header in headers ) csv_line = ','.join( str(dataset[key]) for key in dataset.keys() ) Example for a case of a dictionary mapping a string to a bunch of numbers.
Re: Anti-Patterns in Python Programming
#194Mmm... 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
#195Earlier quoted context omitted.
> The default value gets created when the function is interpreted ("compiled"). No. The default value gets "created" (the expression is evaluated and stored) when the def statement is executed. Take the following example: In [1]: def foo(): ...: def append_five(l=[]): ...: l.append(5) ...: return l ...: return append_five ...: In [2]: a = foo() In [3]: b = foo() In [4]: a() Out[4]: [5] In [5]: b() Out[5]: [5] In [6]:…
I thought that was what he meant. Is there any sharp distinction between "interpreting" and "evaluating" in python that I am unaware of? I've always used the words more or less interchangeably. But now that I think about it that might be a little naive since I have no idea how it works under the hood
Re: Anti-Patterns in Python Programming
#196Earlier quoted context omitted.
I'm not a Python expert, but iirc from various blog posts the "l" variable does not get reset between function calls which will cause undesired behavior. So calling the function 3 times without argument would produce a list of size 1,2, and 3 with the third call rather than 3 lists of size 1. Can any Python guru's confirm?
The key is object mutability. A list type is mutable and a tuple type is immutable. If the candidate correctly deduces what will happen, I'll ask them to write a bug-free version, which looks like one of the below: def append_one(var=None): var = var or [] var.append(1) return var def append_one(var=None): if var is None: var = [] var.append(1) return var Mutability is a very subtle but very important concept to unde…
Re: Anti-Patterns in Python Programming
#197Earlier quoted context omitted.
> if an object is immutable, the behavior of Python matches what the naive developer expects If the object was immutable then append wouldn't work. That's hardly matching expectations.
Why? You would just get a new list back.
>>> [1,2,3] + [4,5]
[1, 2, 3, 4, 5]
Thus appending should do something different than addition. >>> x = [1,2,3]
>>> x.append([4,5])
>>> x
[1, 2, 3, [4, 5]]Re: Anti-Patterns in Python Programming
#198Earlier quoted context omitted.
The key is object mutability. A list type is mutable and a tuple type is immutable. If the candidate correctly deduces what will happen, I'll ask them to write a bug-free version, which looks like one of the below: def append_one(var=None): var = var or [] var.append(1) return var def append_one(var=None): if var is None: var = [] var.append(1) return var Mutability is a very subtle but very important concept to unde…
Since append doesn't return a value, how about: def append_one(var=None): return (var or []) + [1] Would this take longer and/or use more storage for long lists as vars?
And besides all that, there is nothing wrong with doing an append on one line, and returning the variable on the next. It's clear and readable.
Re: Anti-Patterns in Python Programming
#199Earlier quoted context omitted.
In most languages you can't usually: 1. Iterate over a tuple 2. Convert a list to a tuple 3. Construct a tuple of a length not known at compile-time Python allows these because " why not? " but it does break their "one and only one way to do it" rule and confuses beginners a hell of a lot. There are definitely borderline cases. For instance, should a Vector be a list or a tuple? A Vec3 type is obviously a tuple, but…
> Python allows these because "why not?" No, it allows them because the distinction that those restrictions are founded on is only useful in a statically-typed languages, and Python isn't statically typed. > For instance, should a Vector be a list or a tuple? A real vector/array should be its own data type (probably implemented in a C, or similar low-level, extension) that happens to implement the interface expected…
Re: Anti-Patterns in Python Programming
#200I use python for datamining, and most of my work is done exploring data in iPython. > First, don't set any values in the outer scope that > aren't IN_ALL_CAPS. Things like parsing arguments are > best delegated to a function named main, so that any > internal variables in that function do not live in the > outer scope. How do I inspect variables in my main function after I get unexpected results? I always have my mai…
It's very difficult to write automated tests when all logic is in outer scope rather than chunked into functions.