![]() |
Home
| Calendar
| Mail Lists
| List Archives
| Desktop SIG
| Hardware Hacking SIG
Wiki | Flickr | PicasaWeb | Video | Maps & Directions | Installfests | Keysignings Linux Cafe | Meeting Notes | Linux Links | Bling | About BLU |
Earlier I wrote: > Something I have not found is the right whack in the head to get one to > think in pythonic terms and not program like a C programmer. Fully > grokking "list comprehensions" seems a start, but I am thinking I need a > journal article length piece to reread every while until it sinks in. So I did some looking around and found several things that might be useful: 1. "What is Pythonic" http://faassen.n--tree.net/blog/view/weblog/2005/08/06/0 It isn't deep, but if gives some nice examples of how to do things in C, how that translates directly into Python, and then the right way to do it in Python. 2. "Be Pythonic" http://shalabh.infogami.com/Be_Pythonic2 A bit longer, but still only 6 simple assertions with elaboration and examples. It has more depth than is immediately apparent and is worth rereading later. 3. "How to Write 'Pythonic' Code" http://www.chrisarndt.de/talks/rupy/2008/output/slides.html#list-comprehensions Much longer than the first two suggestions, has some profound bits, has lots of examples worth mulling over and rereading later. 4. "Pythonic Defined" http://techblog.ironfroggy.com/2007/06/pythonic-defined.html More haphazard than the others but some good bits. Includes a very short summary of standard Python coding style. Because I have been thinking about it, here are some of my thoughts on the key aspects of Python for a C person: - Blocks are indicated by indentation not by start and end tokens. - Python is interpreted. Actually the ASCII is compiled into bytecodes (automagically: write a foo.py file and a foo.pyc fill will appear once you run it). The bytecodes are interpreted. - Variables are not declared, they are just used. They can be local or global. - Parameters can be positional (like C) but they can also be named, and they can be missing and have default values. - Instead of "#include" Python uses "import". Imports are close to being a lexical insert, but can preserve distinctive name spaces ("import os"), or be flat ("from os import *"), or mangle name spaces ("import os as foo"). Because python is interpreted, the importing has immediate effect--in that sense it is like a library linkage step in C. - Everything is an object and objects are strongly typed. A variable, however, is not typed and it can point to any kind of object. Runtime enforcement is duck typing: 'I need it to quack, and to walk, if it can do that, it is duck enough for me'. - Late binding. Python won't know what type an object is until it sees it at runtime. Object and class definitions can be messed with at runtime, too. - Dynamic. Stuff will pop into existence without explicit malloc-like calls, and things that are no longer needed will disappear without any explicit freeing. - The key data structure is a list (of any data types, including other lists). If you have more than one of something, put them in a list. Lists are ordered and mutable: you can add things and remove things, you can access by index, you can mangle based on an index range. Where in C you would write "for (i=0; i<n; i++) ..." in Python use a list, possibly do: "for my_item in some_list: ...". Assigning a list to a variable is effectively taking its address, assign it to another variable and the two variables point to the same data. Pass a list as a parameter and it is efficiently passed by reference. - A "list comprehension" is a for-loop style syntax to describe a list. It is a far better choice than manually assembling your list in a for-loop. - If you have too many of something to instantiate it all in a list, don't--but pretend that you did! Use an iterator, xrange, generator, etc. Things that respond to key methods of a list, without all that enumerating. - A "generator expression" is very much like a list comprehension but it doesn't build the whole list in memory. - Python is efficient when the underlying grunt work is implemented in C. If you are sifting through a lot of bits in high level code, look for a way to hand that off to some existing library. (The data you will hand off will likely be a list--or somewhat like a list.) - Python can be extended in C, but it is a pain. Consider using pyrex to glue together C and Python. - There is no C-like optimizer in Python, instead figure out how to hand your data to existing libraries. Or, to put it another way: Don't worry about factoring common code out of your inner loop, instead figure out how to not write the inner loop. - Python is procedural, but try to think in functional terms and you might get faster code. - Python loves tuples, they are immutable, use them for heterogeneous data ("(length, width, depth)"), they can be returned from functions, you can assign a slew of things at once via a tuple. A swap would be "a, b = b, a". The key syntax for a tuple is actually the comma, though frequently it seems like it is parentheses. - Python has a neat hash table built-in called dictionaries. Don't over use them. Think in lists and tuples first. - Python strings are immutable, so appending a character to a string makes an entirely new string. Remember that before designing your involved string algorithm. - Python does not include regular expressions in the language, but there are some useful string methods that might save you from having to figure out the regular expression library. - Instance variables are object attributes ("my_obj.my_attrib = 42"). Classes can also have attributes. There are methods you can implement to make getter or setter bottlenecks. - Python does threads, but they all run inside a single threaded interpreter (and so run on a single CPU) and there is global interpreter lock that can starve other threads. (If you really want a lot of threads, checkout the language Erlang...) - Python is currently at version 2.6.2, it is better than earlier versions, great effort has been made to maintain backwards compatibility, so later versions are better. The "other current version" is 3.0.1, it is largely the same as 2.6, but it has made some incompatible changes. Everyone seems to agree 3.0 is an improvement, but breaking backward compatibility makes this a bleeding edge choice. There is a dumb utility called 2to3 that will do the mechanical updating of 2.x code, but a programmer will still need to port unfortunate things. Not all libraries have been ported to 3.0. It is possible to develop entirely under 2.6, but in a 3.0 compatible mode, depending on 2to3 as a build tool to produce 3.0 output, making a final jump to 3.0 as easy as using the 2to3 output as your new source code. -kb
![]() |
|
BLU is a member of BostonUserGroups | |
We also thank MIT for the use of their facilities. |