Is it possible to write purely procedural code in Python, or the OO constructs in both language and supporting libraries have got so embedded that it's impossible to avoid them? Also, is anyone aware of any scripting language that could be considered as "Python minus OO stuff"? (As you can see I'm completely new to Python and initially believed it's a nice&simple scripting language before seeing all this OO stuff that was added in over time)
Many people have answered your question already, but I thought I would share my opinion as well, since I think I understand where you are coming from.
What attracted me to Python was not OO at all but the fact that it was somewhat similar to PHP (which I was using heavily at the time) but allowed me to encode certain higher-order programming techniques that PHP simply could not express. In short, I had become interested in functional programming after reading David Mertz's "Charming Python" tutorials, and after x attempts at trying to port the ideas to PHP, I finally gave up in frustration and started learning Python.
At the time, I was decidedly anti-OO. I grew up around a very liberal, punk-rock, nonconformist culture, and the amount of hype around OO made it too easy to hate (and, I suppose, it still does). PHP at the time was 90% procedural; the prevaling attitude (which seems to have changed with the advent of PHP5) was that procedural code is all you need to solve most problems. With web scripting, it kind of makes sense, because (IMHO) objects really don't have much value unless you can hold onto them long enough for them to be useful, and many web scripts just pipe data from one place to another. Packing the data into objects is kind of like putting your possessions into boxes so that you can move them from one room to another and immediately unpack.
So, I guess you could say, I learned Python in spite of its rich support for OO. =)
It wasn't until I had to implement a large (to me), complex, graphical user interface, that I finally had to get off of my soapbox and realize that I had no better way to create sophisticated GUIs than OO. There are surely non-OO ways to build fancy GUIs, like functional-reactive programming, but a) I don't understand them, and b) I had to get my project done, and used the tools I had and the techniques I knew.
At that time, I started learning about Smalltalk and Alan Kay's emphasis on the "messaging" aspect of OO, and it started making a lot more sense. One of the most difficult tasks sometimes is getting various parts of the screen to update when the user changes a field or clicks a button--in a way that is manageable and doesn't devolve into spaghetti.
Aside from GUIs, however, I am rarely confronted with a task where I *need* OO. As a method for encoding abstract data types, it works, but it seems like more fashion than substance. As many have pointed out, the difference between "method(obj, args)" and "obj.method(args)" is subtle, and often inconsequential. In Python, you can program with just modules and functions/procedures, and never bother with the fact that you are using objects. Sure, a module is an object, and so is a procedure, but it's not all up in your face like, say, Java's arcane restriction that everything belong to some class.
It has been said of Perl programmers that they often dislike abstraction. Sometimes, I really sympathize with this viewpoint. I hate having to use a class that offers no value to the problem whatsoever, merely because an API is hard-wired to use instances of that class. No abstraction can often be better than a bad abstraction, and when it comes to debugging, the last thing you want is a bunch of black boxes.
These days, I do use classes and objects in Python, but mainly as a code organization technique, and only when I actually want my code organized that way. I tend to start with the problem at hand, building procedures to remove redundancy and keep my code small and simple. If I start noticing that a lot of procedures revolve around a particular data structure, I refactor them into a class. This way, I avoid creating abstractions that don't fit. It's much more mechanical than any feigned attempt at "modeling the real world".
I think that functional programming (FP) is a very powerful methodology that can solve a lot of the same problems as OO, and does some things a lot better. FP and OO can live in harmony to some extent, but there are some places where they contradict each other. For instance, FP offers a mind-blowingly powerful tool called pattern matching, which is like a switch/case statement on steroids. OO dogma insists that this "violates encapsulation", and that any form of switch/case is evil... replace conditional with polymorphism... replace conditional with polymorphism... replace conditional with polymorphism... repl<hic> On the other hand, implementing something as seemingly simple as a "__str__" method in functional languages can be surprisingly non-trivial.
The lesson to be learned here is that each methodology (including strctures/procedural) has its strong points and weak points, and there are always tradeoffs to be made. OO's biggest strong point is that a lot of people grok it, so it's a fashionable and friendly user interface for a programmer. Python in particular emphasizes this point with its no-nonsense, lightweight approach to defining classes and using objects.
However, and this really the main point I wanted to make: *no* paradigm is sufficient to solve any interesting problem. I have gotten sucked into coutless language and paradigm pissing matches only to go back to my desk and try to finish a project I'm working on and realize that (gasp!) programming is still hard. It never stopped being hard! And sometimes the methodologies just create additional work (cf. jwz's comment on regular expressions: "now you have two problems").
The best way to crack through tough problems is to learn as many methods and techniques as you can, and develop an intuition for "the right tool for the job". What matters most is that you solve the problem at hand, in a way that people can hopefully understand and maintain later.
Good luck, Dave -- http://mail.python.org/mailman/listinfo/python-list