No worries, always happy to share the knowledge of the Python stdlib :)
I'm still at a bit of a loss as to how this can't be solved by common Python functions. i.e. if your requirements are to add package dependencies, that should be solved by pip/setuptools (requirements.txt or setup.py or a combination of). Python has introspection capabilities second to none. If you need to look up the inheritance tree of a class, you can easily do so (although I understand that this isn't your particular use case).
Here are the major flaws I see with your solution (of course, just IMHO, so take it with a grain of salt :)):
- It doesn't conform to standards. Someone looking at this (especially one who has spent quite a bit of time with Python) is likely to to say "wat?". The stdlib and supporting cast should /always/ be exhausted prior to rolling your own solution. Not only will you benefit from a solution that's thoroughly tested (and reviewed by core devs), but you'll also benefit from learning about areas of the stdlib that you were previously unaware.
- Huge margin for human error. At any point, a programmer can forget to add a dependency. As your code base grows, I'd imagine that the problems would be more and more difficult to track down.
- The attribute name is confusing. "Dependencies" in OO-land (not saying that Python is strictly OO, I'm simply referring to your examples) means "base classes that this class depends on". Introducing a "depends" attribute to a class that has a different function would likely be confusing to those reading your code. (I also realize that this can be trivially changed, just calling it out as it's in your example)
If your only requirement here is to get a full list of dependencies, why not use inspect.getmro
? For example: http://codepad.org/k7iGWYFf
Although I might be off with what your requirements are because I noticed there isn't any actual inheritance going on in your example.
A couple things here:
What are you actually trying to achieve? If you're trying to determine which subset of a list is of the type that you're looking for, wouldn't it make more sense to use
filter
? (Might not be what you're doing, but I've seen that logic applied before, which makes me cringe).-
It would also be worthwhile noting that
isinstance
will also yieldTrue
for instances that subclass a given class:In [1]: isinstance('asd', basestring)
Out[1]: True
In [2]: type('asd') == basestring
Out[2]: False
@forivall: If unary + prefix to coerce to number is part of your project's style guide, I would feverishly argue that the style guide should be changed. Using language hacks over features implemented specifically to solve the same problems is essentially just a way for a programmer to say "Hey guys, look how awesome I am!".
Code should be just as easy for someone brand new to the codebase to read as for the person who wrote it. Someone not familiar with your project's "style guide" will spend time figuring out what's going on and why it's being done that way. On the flip side, using the obvious functions will incur no reading overhead.
Cool, so let's all make our code /less/ readable!
If you know that your decorator is always going to be called by a class method, you can also do this (and I also encourage the use of functools.wraps
):
def will_change_state(f):
@functools.wraps(f)
def wrapper(self, *args, **kwargs):
ret = f(self, *args, **kwargs)
self.change_state()
return ret
return wrapper
Increasing readability never hurts. (I also added **kwargs
in there out of habit).
A little more readable version might be:
from itertools import chain
list(chain(*lists_list))
list(chain(*tuples_list))
I say more readable because sum is using the specialized implementation of adding two lists (or tuples). Without knowledge of what's going on under the hood, this would likely confuse the reader. The hood is opened when mixing a list and a tuple as elements of the parent list:
>>> m = [[1, 2], (3, 4)]
>>> list(sum(m, []))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
However, this still work with chain as it only cares that the elements are iterables, not their types.
First off: "Sometimes you are working on some project and you don't want to push the code to Github or similar, but you want to have it everywhere or just back it up so you don't rely on some of these providers"
Err, as you're using it, isn't this just another such provider? ;)
Don't get me wrong, I kind of see the benefit (if you don't have your own, say, Vagrant scripts to easily set up identical development VMs), but if the intention is just as a form of repo hosting, I'd still much rather go through private Github or Bitbucket services..
Do they allow access to framework code? If not, I could see this as being a show stopper for me.. Far too many times I'm setting breakpoints deep in framework code to debug issues.
[I think the comment system is a little broken atm, so posting this in its entirety again]
(Ignoring the logic error in the third case of the switch statement and the functional difference between the two examples)
I'm a little confused by this statement.
There /are/ cases when switch statements are executed more efficiently, but that has nothing to do with the reason given in this post (which is just flat out wrong). See http://oreilly.com/server-administration/excerpts/even-faster-websites/writing-efficient-javascript.html. However, who knows how many interpreter optimizations have been done since the time of that writing.
Having said that, switch statements are usually preferred over if/elseif to greatly improve readability. However, the efficiency difference is arguable at the very least (and that's when talking about it at the interpreter level, not logical flow).
So, now when someone looks at your Django project expecting well known Django configuration, they'll be left thinking..
"Uh, wat?!"
Now, supplementing Django's routing with Pyramid's traversal routing system.. That's an entirely different conversation altogether :)
@typicalprog: What if posts and authors reside on different shards? :) Sometimes (albeit not very often), denormalization is required in order to achieve your load requirements.
Having said that, I much prefer JOINs if you're sitting on a single shard.
Python does not have xor operator implemented as !=:
As you can see, these both generate different bytecode (the first calls into longrichcompare and the second calls into longxor in longobject.c).