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 an opinion, not a best practice. I would argue that either the loop is a one liner, at which point use whatever you want (x works well), or it's more than one line and then I want a proper name for the thing you are iterating over.
`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.
> Even if ary.last is one more character, it uses less of my brain to read than ary[-1]
This has nothing to do with whether it's a good idea. If you read a lot of python code, the latter is easier to grok. And when you have separate ways of doing things, it takes a longer and longer time to absorb those idioms and internalize them to the point where you don't need to think. Adding a bunch of "convenience" methods that do minor permutations on common operations might read better when a line of code is given as an isolated example, because it can read more like an english sentence. But when you're reading over code, the resemblance to english only helps when you're looking at application code which isn't a part of the language or standard library. Having the language and standard library present a single way to do things makes it easier to get to a base level of familiarity.
Endless variety in doing simple things doesn't buy you much.
That being said, the python stdlib is full of stuff built up over many years, so it doesn't follow that idea everywhere. Also, higher level design is never going to fit into the TOOWTDI concept because things at that level are more subjective.
Personally, I do agree with having ary[0] as the "one true way". Doing ary.first will lead to ary.second, which will lead to ary.slippery_slope :). I mean some conveniences are good, while having too many is evil.
> Also, you're incorrect about help(). help(Foo.highlight) will provide the docstring for Foo.reverse if Foo.highlight = Foo.reverse.
That's what I was trying to say. When doing help(Foo.highlight) I want it to say something like "Event handler for highlighting text", not "Reverse pixel color for the given rectangle."
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.
And possibly allow indexing: `department[3]`. Yeah, I don't like that. It's not clear whether it's a generator or a full sequence. Generators when you don't expect them are evil (you cannot iterate over them twice). I would much rather see something like department.get_employees() and department.iget_employees() that return a tuple and a generator respectively.
That's the sort of things people used(?) to complain about C++: gratuitous operator overloading. It sometimes makes sense, but you really need to think long and hard about the semantics.
Second, using `each` for a generic iteration variable. This is an opinion, not a best practice. I would argue that either the loop is a one liner, at which point use whatever you want (x works well), or it's more than one line and then I want a proper name for the thing you are iterating over.