Metrol’s Development Corner

March 18, 2008

PHP Looking at Python

Filed under: Web Development — Michael Collette @ 11:15 am
Tags: , , ,

Have a look at any message board that is silly enough to actually mention PHP or Python in the title and you have all you need for a virtual battle for the “P” in LAMP. Not to be forgotten is Perl, but that one will have to wait for later. Today’s post will attempt to look at Python from the eyes of a PHP programmer. I will not promise an unbiased viewpoint, but I can tell you right up front that both languages fill a niche for getting certain jobs done quite nicely. Both languages also have some really odd ball things to them… usually for very good reasons depending on how you feel about those reasons.

Although it sometimes feels like there’s a new programming language coming out from somebody every couple of weeks, I believe it is now fair to say that both PHP and Python are very well established platforms for development. Both enjoy considerable corporate support, as well as very active user communities. They also jump across the operating system divide reasonably well.

The following is not meant to be a full tutorial on the Python programming language for a PHP developer. I would hope that it would make reading a full tutorial a good bit easier. Python is a rich language with a wide variety of capabilities. If I leave a few of the Python details out of the picture I just want you to know up front this is not meant to bolster PHP.

Where They Came From

Most PHP folks have already heard the story so many times as to cause eyes to roll when yet another site gets into the history of their platform. Sorry folks, need to do it here again. I’ll try to keep it short.

PHP started as a set of Perl scripts to solve some form processing issues on the author’s web site. They were his Personal Home Page tools, and thus the acronym was born. Over time the number of those functions increased to a point where PHP was becoming a full language itself. Eventually the engine was moved to C and the Personal Home Page tools meaning was dropped. Today PHP is no longer an acronym, just the name of the language. At it’s core from its very earliest days PHP was a procedural language to get things done on the web quickly and easily.

At the time Perl ruled the dynamic web site game. For all the good or bad you can say about Perl, it was outpaced by the ease of use that PHP provided programmers. When PHP got matched up to a MySQL database that’s when things really started to shine. Put those two on a Linux machine running the Apache web server and the LAMP stack was born. PHP didn’t really need any of the other parts, as it ran on other operating systems with different web servers and could talk to a wide variety of database engines. Still, LAMP is where the success really took off.

Python started life a bit differently. Where PHP sort of became a programming language almost by accident, Python began life as a better way to develop a general purpose programming language. Object oriented at it’s core, but still supporting procedural methodologies so it could be used for scripting as well as a scalable programming language. It too was focused on simplifying the life of developers by taking care of memory management and removing extraneous syntax.

How Different Are They

Once you get past some of the definitions the languages use to describe certain aspects about themselves, there are more similarities than differences. To be sure, there are differences, but many of the same programming structures you would do in PHP look very similar in Python. You’ve got “if” statements, “while” loops, strings, integers, classes, objects, inheritance and enough tools in either language to carry over knowledge from one to another.

What is notable about Python, compared to most languages, is what it doesn’t have. Mostly, a lot of the carry over syntax from C and Perl that got stuffed into PHP. If you’re making the leap into Python say goodbye to your good friend the semi-colon “;”. In Python the end of a line is the end of the command, so there’s no need for them. They can be used for compounding multiple statements on a single line, but that’s just sloppy no matter what language you’re talking about.

You can also say goodbye to those lovely curly brackets “{ }” to define your “if” and “while” structures. In Python you define a structure by spacing. Here’s a quick look at some very basic PHP and Python code illustrating the difference.

-----------------------------------
<?php
$x = “Howdy”;
if ($x == “Howdy”) {
  print “Howdy back atcha!”;
  $x = “”;
}
?>
-----------------------------------
#!/usr/env python
x = “Howdy”
if x == “Howdy”:
  print “Howdy back atcha”
  x = “”
-----------------------------------

I’ve included the PHP tags and the “#!” so you know which language is which here. In the Python example you’ll note that the “print” statement is indented following the “if”. This isn’t just good style, it’s a requirement in Python. Every command indented along with that “print” is considered a part of the “if” block.

Most comments I have seen out there by folks who don’t like Python point to this single syntactic detail as a reason for their dislike. The notion that using proper style as a part of the language’s syntax is just wrong in their eyes. From Python’s perspective, any decent programmer is already going to be indenting their code in this fashion, so why not lose all that extra cruft and make it part of the syntax? Furthermore, by getting rid of that extra junk there will likely be fewer syntax errors due to the missing brace or semi-colon.

Python makes a good point here. I doubt there’s a single PHP developer alive who hasn’t been caught by a missing semi-colon, or improperly nested brackets. In practice, I definitely don’t miss those semi-colons which aren’t much more than a legacy from C. I do miss those curly brackets though. Especially since my text editor is able to automatically show the matching brace when the cursor is near by. With nothing but indentation defining code I find it a little more difficult to visually define a block.

Issues of style are highly subjective. You could argue that Python’s layout looks more like a page layout made up of paragraphs. Without the extra punctuation source code can look cleaner. Even though Python essentially uses style to define blocks, there are still numerous ways for a programmer to obfuscate the code. When it gets right down to it, the readability of the source code is still up to the programmer to follow the style guides the language encourages.

You should also notice the difference in the variable “x”. There is no special character, like PHP’s “$”, to define a variable. The variables do look a bit cleaner, but once again without some way of flagging an editor there’s no good way to highlight variables. Another minor annoyance is that you can’t do something like:

$name = “Bob”;
print “Howdy there $name”;

You would instead have to do something like this in Python:

name = “Bob”
print “Howdy there “ + name

Hey, where is the “.” dot connector for strings? Python uses “+” to concatenate strings. This turns out to be a much smarter way of doing this. By not using “.” for string concatenation Python can use that dot for accessing object methods. As opposed to PHP using Perl’s nasty looking arrow thing “->”. I’ll get into object model a bit later, as this is a huge part of what makes Python what it is.

Lists, Dictionaries, and Tuples Oh My

There are other notable syntax differences, but these are usually pretty straight forward to mentally convert over to. One of the nastier stumbling blocks when reading about Python is trying to keep track of what a List, a Dictionary, and a Tuple are. These are essentially overly fancy names for arrays.

Lists and Objects

The following is an example of an index array in PHP and a list in Python.

-----------------------------------
<?php
$z = array(“stuff”, “things”, “widgets”, “gizmos”);
print $z[2];
?>
-----------------------------------
#!/usr/env python
z = [“stuff”, “things”, “widgets”, “gizmos”]
print z[2]
----------------------------------

Both of these create a list of strings that can be accessed by an index value. Where the two languages diverge is how you deal with this data. Let’s start by adding a new element to each then sorting the data.

-----------------------------------
<?php
$z[] = “garbage”;
sort($z);
?>
-----------------------------------
#!/usr/env python
z.append(“garbage”)
z.sort()
-----------------------------------

This illustrates a fundamental difference in how these two languages view data. In PHP, the variable $z is the container for the array in question. Since $z actually contains this data, it would make sense that in order to do something to that data you would need to pass it on in to a function to process it.

This list of elements in Python is actually an object, with z acting as the pointer to that object. An object carries with it the actions that can be performed on it via methods. In this case, it makes sense that rather than passing z to a function you would instead access a List Object method to manipulate it. In a really rough way, you can think of it like the following PHP class.

<?php
class ListObject
{
  $listData = array();

  public function __construct()
  {
    foreach (func_get_args() as $arg) {
      $this->listData[] = $arg;
    }
  }

  public function append($data)
  {
    $this->listData[] = $data;
  }

  public function sort()
  {
    sort($this->listData);
  }
}
?>

Again, this is a really rough way of looking at what Python is doing. When you created that list called z you were actually creating a new object. Like if you were to do the following in PHP.

<?php
$z = new ListObject(“stuff”, “things”, “widgets”, “gizmos”);
$z->append(“garbage”);
$z->sort();
?>

Everything in Python is considered an object. When you create a list, dictionary, a string, etc., you are in actuality creating a built in Python object of that type. This has provides for benefits that a Python developer can make good use of.

PHP has 75 functions to deal with handling arrays. They all have to exist in the global namespace, so you can’t put together a user defined function using any of those names. Python doesn’t run into these kinds of namespace issues.

You can actually extend Python’s built in types. So, if you need a method to deal with a List that Python doesn’t have then you can easily add it in through inheritance.

Since Python’s built in types are run in C the methods are wicked quick.

Cleaner namespace, faster execution, extendability… what’s not to love?

For PHP, giving over the ability to override a built in function is a no go. Not because the language couldn’t allow something like this, but it starts into issues with the integrity of the commands. When you ask for a sort of the elements in an array you always know that you’re running the real sort function. In Python things may not be that straight forward.

This is also not because PHP isn’t object oriented from the get go. Even a language like Java, which is also very centered around the notion of objects, doesn’t allow overriding built in methods. For some, Python’s flexibility in this regard is seen as a good thing, where others may regard this as a liability.

Not only are creating and filling lists different under the hood in Python, but getting data back out has some pretty cool features to it. The first time I saw a setup like this was way back on Atari Basic (okay, I’m really showing my age here). Python calls it “slicing”. Here’s how that plays out:

#!/usr/env python
print z[0]

Nothing too special there. That outputs “stuff”. Now here’s a taste of the clever stuff.

#!/usr/env python
print z[0:2]

So that’s kind of odd. What you get back from that is ['stuff', 'thing']. This outputs a list, as denoted by the brackets, with the first 2 elements. I’ll leave the full story about slices to a more complete Python tutorial, but this is one of those features that once you get acquainted with it you’ll be looking over the fence at Python’s yard in envy. It also knocks out an entire stack of those array functions PHP relies upon.

I won’t be getting into it here, but strings are dealt with in a similar way. Instead of substr() kinds of functions you use slicing to pull out portions of text.

Dictionaries

So if a list is sort of like an indexed array, what is a dictionary? Pretty much an associative array. You get to put items into this array using key/value pairs.

Just when you thought you would see the last of curly brackets “{ }” by jumping to Python, they come right back with dictionaries. Where a list uses brackets to frame up the data list, curly brackets frame up dictionaries.

-----------------------------------
<?php
$z = array( “stuff” => 2,
            “things” => 42,
            “widgets” => 37,
            “gizmos” => 12 );
print $z[“stuff”];
?>
-----------------------------------
#!/usr/env python
z = { “stuff”: 2,
      “things”: 42,
      “widgets”: 37,
      “gizmos”: 12 }
print z[“stuff”]
----------------------------------

Like lists, dictionaries are an object type with a variety of methods for manipulating them. As you might well imagine, you deal with these a good bit differently than what you would expect from an associative array.

Rather than getting into the details of dictionaries, I would like to point out one advantage to this overall approach versus what PHP does. Picture one such array in PHP that you have built up. You then add a key/value pair where the key is an integer. Wrap it in quotes all you like, PHP will take that and make it an index value even though what you wanted was an associative style key/value.

Python doesn’t suffer from this problem since a list and dictionary are independent objects. In a dictionary, a key is always a key. I really think Python’s approach to explicitly separating these two kinds of grouped data is a huge benefit.

Tuples

Finishing off the stack of data types that hold multiple values we have the “tuple”. Simple as I can put this, a tuple is a list that the values of can not be changed in place. If you were to actually study up on Python you would most certainly be well versed in “mutable” and “immutable”. Not getting into all of that here beyond saying that a tuple is immutable since it can’t be changed.

For example, when I sorted the list earlier that actually altered the list object in place. A tuple can’t be altered in place, so you won’t be running a sort, or any other method that would alter it. So why have tuples at all? One reason for them is a degree of data integrity. Since they can’t be altered, you know that when you pass a tuple around it retains it’s value. More importantly, tuples can be used in places where lists can’t be. Things like function calls and such. In fact, you see something like a tuple all the time in PHP without thinking about it.

So lists have brackets “[ ]“, dictionaries have curly brackets “{ }”, and tuples have parenthesis “( )”. Pretty much any time you see values in parenthesis you’ve got a Python tuple.

-----------------------------------
<?php
$z = array(“stuff”, “things”, “widgets”, “gizmos”);
print $z[2];
?>
-----------------------------------
#!/usr/env python
z = (“stuff”, “things”, “widgets”, “gizmos”)
print z[2]
-----------------------------------

I could go on for a while about the various syntax issues between the languages, and many very good books do just that. Time to dive into more controversial stuff.

Object Oriented Code

Both of these languages now support object oriented design, thanks to PHP5. Python has always had this in place, but it’s model is a bit different. Python uses “class” to define objects, like PHP. Unlike PHP, Python objects are pretty much wide open at all times. There’s no concept of “private” or “protected” members or methods. Any data member can be altered by any code accessing that class. You can even dynamically assign new data members to a class without having to do so in the class itself.

You can simulate similar behavior with PHP’s __set and __get magic methods. With Python, this kind of dynamic assignment is built in to every class, whether you want it or not.

If that last sentence sounded a little biased, my apologies. I was hoping it would sound very biased.

In my personal opinion a class should be a fixed blueprint used to define an object. Python seems to see a class as just another means for wrapping data into a container with inheritance benefits. Depending on how you view OOP design issues this may be a good or bad. Even from a PHP perspective, which plays fast and loose with a number of design issues, Python’s approach may be a bit much in providing flexibility.

Inheritance

With PHP a class may inherit from exactly one parent. That parent can in turn be inherited from another parent and on up through any number of generations. Python can of course inherit from a parent, but it’s not limited to just one. You can inherit numerous parent classes into a single class.

Languages that restrict inheritance to a single parent, like PHP, usually point to naming conflicts as the reason for the restriction. Python deals with that by providing for a specific search order to how it looks for methods or members in the class tree. For example:

class MyClass(Parent1, Parent2, Parent3):
  pass # an empty statement

Let’s say you have a method called doSomething() that is in one of those parent classes. Python begins at the lowest level of the tree, then at each level goes from left to right looking for that method. In the above example the search starts with Parent1, then to Parent 2, and so on. If it isn’t found, on up the tree it goes and repeats.

The cool part about this kind of inheritance is that you can have a number of utility classes that can be inherited into a wide variety of classes. Things like database handlers, file management, or text processing. You can maximize the reuse of your code by just inheriting into the class you’re writing and away you go.

There’s a hidden cost here though. Well, a number of them actually. As restrictive as PHP is about inheritance, you always know there is going to be a linear path from the lowest child to the top of the class tree. Tracking back is a relatively simple process. Allowing multiple inheritance opens the door wide to creating a maze of class trees to climb through.

A more fundamental problem here is the notion of “IS-A” and “HAS-A” relationships. This being a metaphor that developers can use to determine whether or not you should inherit from a class or use an object from that class. By allowing inheritance from multiple parents this metaphor is an easy one to break, thus muddying up the waters of what is considered proper OO design.

Of course you don’t have to actually use multiple inheritance in Python. You can structure your code as you see fit. The problem with allowing this at all comes in when you need to work on or with someone else’s code. Did that other person already merge an unrelated class into the tree you wish to inherit from? How wide is that class tree you’re wanting to inherit from? What kind of time is involved with hunting all of that down?

You can run through these arguments back and forth for a while. You’ll certainly see this in mailing list threads as the “proper” way to handle OO design is debated. How much importance you put on being able to control access and structure of your classes will be a determining factor in whether Python is right for you. Java is on one extreme of defining exactly what a class is, and being able to lock it down. Python over on the other extreme with a focus on flexibility. PHP sits sort of between the two in this regard.

Class and Methods

Back in my earlier post discussing and introduction to Object Oriented Programming for PHP is made heavy use of a Product class. Here I’ll present to you a similar class as it would appear in Python.

class Product:
  model = ""
  description = ""

def __init__(self, index):
  self.pullFromDatabase()

def showProductSpecs(self, index):
  # Some clever display code

def displayProductPrice(self, index)
  # Clever price calculations returned

def pullFromDatabase(self, index)
  // Fancy database query would run here
  self.model = dataRow[“model”]
  self.description = dataRow[“description”]

No curly brackets, and no semi-colons. Instead of __construct() you now have __init__(). Both of those methods do the same thing, run when an object is created. The other big difference you should have noticed is that “self” stuff in the argument list for every method. This serves the very same purpose as “this->” does in PHP. For some reason Python decided that just having that automatically pass into a method wasn’t explicit enough, so you have to pass it in through an argument.

The other, and probably more valid, reason for having to explicitly state “self” in the argument list is due to the fact that there’s really no such thing as a “static” method in Python. When you define a method without “self”, it essentially becomes static since it doesn’t have access to an object instance that its class created.

In all fairness, the need for static classes in Python may be a moot point. The main reason they’re handy in PHP is due to being able to group what are essentially procedural functions within the namespace of a class. Python doesn’t have the namespace issues of PHP, so needing to group functions into a class is generally something you wouldn’t need to do.

Using a class to create an object is as simple as…

p = Product(12)
print p.showProductSpecs(12

Looks like I missed the “new” command. If this were PHP you’d be right, but in Python there is no keyword for creating an object. Everything is an object, so any time you see an assignment like the above happening an object is being assigned to a pointer.

Using an object is pretty much the same as with PHP, just a dot “.” instead of that dash arrow thing “->”.

Namespace Handling

A file containing functions, variables, and classes in Python is considered a “module”. Importing a module from one file into another doesn’t (by default) just jump into the global namespace. In fact, Python doesn’t even have a concept like a global namespace. The scope of naming exists within a module at the top most level.

To briefly illustrate this point let’s pretend there is a function called doSomething() in the file “MyLibs.py”. You want to utilize this function in the file you’re working on. Here’s how this plays out in the code.

import MyLibs
x = MyLibs.doSomething()

There are a wide variety of variations on this theme. You can change the import line to read “from MyLibs import *” and not have to specify “MyLibs” to call functions from it. That line could be tweaked to only import the functions or classes you specifically want to utilize, or even give a specific name to how you access resources from that module. I won’t bore you with all the details of dealing with modules. These are some very powerful tools for bringing in code from other files without running into the kinds of namespace issues that PHP suffers from.

Python only has a about a dozen or so reserved keywords as a part of the core language. As I mentioned earlier, PHP has 75 keywords just to deal with array functions. Python allows a programmer to keep a fairly tight rein on the allowed scope of the namespace, where PHP throws tons of stuff into a global namespace that everything has to fit into.

Clearly Python has much better structure in handling namespace. The only down side to this is that you really can’t define a global constant. In PHP these can be pretty handy for dealing with site preferences and other pieces of information that need to cross scope boundaries. I’ll grant you, that’s a very minor point, but one to be aware of if you’re looking to migrate code to Python from PHP.

What Got Left Out?

In short, lots! I warned you up front this was not going to be an attempt at a full Python tutorial. I didn’t get into string handling, or differences in “for” loops. For the purposes of this post I believe much of that to be minor issues of syntax that a reasonably competent PHP developer would pick up on through a true tutorial. Those things are handled differently between the languages, but I don’t believe they do all that much to illustrate the conceptual differences.

Advanced Python topics like threads were left out since PHP doesn’t support them, and I wouldn’t have done the topic justice in this format. This is the same reason why GUI development and/or network sockets weren’t discussed either. There’s really good reasons why there are big fat books that cover the full scope of capabilities. Both of these languages do a lot of stuff!

Summary

At the beginning of this post I talked about what drove these languages forward from their early days. Even after all these years most PHP code is produced to do one basic task, get to that closing </html> tag as quickly as possible. Run through things as quickly as possible, then dump out of memory just as quickly to get ready for the next page. This all obviously stems from the fact that PHP and web development go hand in hand. This is a task that PHP was built for and does a fine job at. Certainly PHP is capable of more than that, but I would venture to guess that PHP use away from the web is fairly limited.

Python is a general purpose platform, that can also be used for web development. You could use it to script web pages, or even program the web server itself. It’s proven itself as a fine GUI development platform with a wide variety of supported widget sets that can run on multiple platforms. It integrates well with Java, and can make use of C libraries. Anything from a simple shell script to an advanced multi-threaded application can make good use of Python.

Each of these languages have strengths and weaknesses in their approach to solving the universal problem of how to tell these stupid machines what to do. Ultimately it’s up to you to determine which of these solutions best fits the problems that confront you.

If you are already knowledgeable in one of these two languages I would recommend the following.

  • Listen to the supporters of each. They can provide valuable insight into why these platforms do things the way they do.
  • Ignore suggestions pointing you to use this language or that. Always keep in mind that humans have a basic need to feel justified in their decisions. Getting others to agree with their world view helps to do that for them, but most likely will do little for you.
  • Focus on the languages that are getting talked about the most, and where actual applications are coming out of. If certain languages are getting little attention there’s probably a good reason why.
  • Get knowledgeable about C, C++, Perl and Java. Both PHP and Python derive quite a bit from these languages, even if what they got out of one or the other was to not implement something.

Hopefully I’ve provided a reasonable comparison of these development platforms to you. Leave a comment below and let me know what you think.

1 Comment »

  1. besides the syntatic diffs b/w php/python, i’m really concerned about the lack of built-in functionality for session handling and the fact that you have to download and install a separate extension to be able to connect to a MySQL database. Apparently the MySQLDB extension isn’t yet available yet for Python 2.6 or Python 3.0.

    So this is that scenario where if you’re on the web, you’re stuck in python 2.4/2.5. I don’t like that.

    Session handling. Appears very manual. I saw a couple of “recipes” for session handling with code like:

    headers = {}
    headers['Content-type'] = ‘text/html’
    headers['Set-Cookie'] = ’sid=%s;’ % sid
    print_headers(headers)

    That’s ok, but shouldn’t it be “higher level”? session_start() anyone? I mean come on. It isn’t that big a deal, but if Python wants to be taken seriously as a web development language, they really should automate a lot of this stuff and integrate it as a core part of the language.

    I can’t wait until I try file uploads…

    # Read the file in chunks
    for chunk in fbuffer(fileitem.file):
    f.write(chunk)
    f.close()
    message = ‘The file “‘ + fn + ‘” was uploaded successfully’

    Looking at this now, I kind of LIKE the low levelness of this code.. it opens the door for perhaps programming a progress bar and stuff.. it seems like python gives you far more control over this code..

    I don’t know yet. :) .

    Comment by bobobobo — December 29, 2008 @ 12:36 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.