I’ve recently taken on a gig where I am writing Python code because the work is mostly done in Python and they want it to be maintainable by the original team members.
I have to confess that Python was my gateway language into the world of non-rigid Java nastiness but this is the first time I’ve ever used it proper hard in earnest for money.
In my Ruby practice I’ve recently changed the way I write code pretty radically. I now
- tend to write very small methods that just do one thing, I write tests that test those one things. I usually write the tests first.
- I’ve also started using little lambda functions and passing them into other wrapper methods that just need to call the processing hidden in the lambda.
- Every time I see lots of assignments one after the other I’ve started using tap or returning to protect me from my own stupidity.
- When I see case statements I tend to create a little helper class
- I will create little classes inside the current class so I can just ask them about things instead of writing procedural code. I can also test them too if I need to.
- Really getting away from writing long methods full of procedural code. They are a sod to test and confusing to read.
Now I’ve done some Python I’ve realised that there are a few things I like:
- Files are modules, and namespaced. This is a little odd at first but I like it. It means you could do without classes if you wanted, maybe.
- I’m on the fence with objects needing to have self typed everywhere. I can see how it’s easier to create an OO style quickly if you force the coder to put self everywhere, but it feels heavy. It also feels right because you can’t do stupid assignment bugs like you can in Ruby, or rather the bug shouts out at you when you have.
- I like list comprehensions, but they seem really heavy after using blocks for years.
- I like how (like Ruby) you can pass references to functions around, and I think the syntax is superior.
- I like the built in help. Ruby’s is not built into the classes the way Python’s is and you often find yourself digging round on the web for a while when a couple of commands in the Python interpreter and you’re away.
I don’t like (as in … why?):
- I don’t like procedural-style conversion functions polluting the top level namespace, but I have understood that (for example) list is really a class that you initialise and isn’t really a function. It just looks like one.
- Ruby enforces a convention that classes (i.e. constants) all begin with a capital letter. It seems silly, but not having an enforced convention makes unpicking code harder than it needs to be. I think the first point would have been easier to get my head around if I’d been able to see that these conversion functions were actually class constructors. Java has the convention of upper case classes but doesn’t enforce it – this is a major pain, or can be.
- Python has a built in complex number type, but doesn’t have any native syntax for regexp. I was looking in the Python docs and there was some nonsense about not needing syntax because you don’t use regexp much and typing strings is fine. Utter crap, I use them way more than complex numbers. Plus if you want a complex type in Ruby it’s really easy to make one and just drop it in. Always having to screw around with strings is one of the things that makes Java so unbearable. I like syntactic sugar and syntactic checking, makes life easier and it’s relatively trivial to add in. Just lazy not to, and it shouldn’t be dressed up.
- Overriding methods like + and so on is a bit hard, because of the method naming. Not too bad, just irritating.
I got a copy of Learning Python, and I’m about 40% of the way through it. No significant mention of objects at all yet. I mean, the word has been used, but not the thing. Just loads of procedural code examples. I’m beginning to think that this is a function of how the language grew. It was picked up by a lot of folk who were moving from hoary old procedural environments, like Fortran, and who were used to thinking in huge chunks of code. So it gets taught that way, and people pick up habits that are bad, and hard to improve upon. I’m almost tempted to put together my own book that puts the objects first, but don’t have enough time to do the things I need to do as it is.
So the first Python module I picked up as an example of how to do the work I’m doing was 300 lines of procedural code. I ignored most of this and started with unittest and worked backwards into some simple classes that do a similar job in about half the code (not including tests). So it is possible to write nice clean BDD Python code, but doesn’t seem to be part of the culture. The examples aren’t very good.
I think it’s a good language and don’t mind using it, but there is definitely a problem with object orientation and design being treated as something for the adults and maybe only later that I think needs to be addressed.