5

My Notes On Learning Python Coming From Perl


Posted by Artem Russakovskii on October 9th, 2008 in Programming

Updated: January 2nd, 2017

image

I’m learning Python. Since I’m currently primarily a Perl coder, I decided it’d be a good idea to post and keep track of my experiences coming from heavy Perl. I have a few reasons for learning Python, which are:

  • to see what else is out there and broaden my horizons.
  • to keep my brain active by feeding it new tasty information every day.
  • to become a more valuable employee and potential future candidate.
  • to learn a new language, especially one used by giants like Google.
  • to learn a new OO language, as I’m tired of Perl’s hacky OO.
  • to build GUI applications. GUI in Perl is a big pain. I’ll see about Python.

So, without further ado, here are the notes [WORK IN PROGRESS], split by virtual chapters that I made up myself:

Chapter 1.

  • I’m using Eclipse for most of my development. E.P.I.C. is the plugin that adds Perl support and it works quite well. For Python, I downloaded the Python plugin called Pydev. It seems to work quite well as well. The only thing so far I wouldn’t use Eclipse for is PHP because PHPEd trumps all competition (though there’s an Eclipse PHP plugin called PHPEclipse). A quick way to see the plugins you have installed just click Help->About.

image

  • Tuples are just immutable lists? a = (‘b’, ‘c’) is immutable while a = [‘b’, ‘c'] is just what a regular list in Perl is. I’m not sure what to make of it yet and whether it was worth it giving up such important syntax as () for that.
  • I hate ActiveState’s PythonWin console (the editor itself). Ctrl-Up for history and regular Up for traveling around the code? WTF? Though I do like that there are intellisense-like features in it.
  • I miss the $, @, %, etc in front of variables. It’s so easy to tell what is a variable and what is not, what type a variable is, as well as insert it right inside quotes.
  • I began to understand how many things in Perl I took for granted.
  • A hash is called a dictionary in Python (created with { } ). Hash keys are separated from values via “:” instead of Perl’s “=>”. For example, dict = {“a” : “b”, “c” : “d”}. In Perl “=>” and “,” are the same, but in Python “:” and “,” are very different and cannot be used interchangeably.
  • At this point I really like the OO feel of typing in a dictionary name, followed by a dot and getting a list of class methods as opposed to Perl’s non-OO approach. Since I’ve been looking to get back into a more OO language than Perl but not as OO as Java, I think Python may be the right fit. We’ll see…

image

  • Now the book (Wrox Beginning Python) mentions the dict.__contains__() function, which looks internal to me. Why did they not instead use the dict.has_key() function? They look like they do exactly the same thing. Why did they start from functions that are supposed to be hidden in the first place?
  • There are special values True, False, and None, which correspond to 1, 0, and undef (?) in Perl.
  • list.remove(VAL) function looks useful. I don’t think Perl has anything like it. It removes the first occurrence of value VAL in list.
  • If you list.append() another list, it appends a sub-list object, while list.extend() actually extends the list with another list. In Perl list.append() would correspond to pushing an array ref and list.extend() would be pushing an array itself.
  • You can compare 2 sequences (lists, tuples, dictionaries) with ==, just like numbers. In Perl, if you try @a == @b, only array lengths will be compared.
  • string concatenation is done via “+” vs Perl’s “.”.
    1
    
    str_final = str1 + " " + str2
  • The print function has a couple of quirks in Python. print implicitly outputs a space between expressions, and it also implicitly outputs \n after the last expression, unless the last expression is followed by a trailing comma (,).
    1
    2
    
    print "hi", "I'm",
    print "still on the same line", "but will end the line now"
  • Variable substitution is separated from the print statement by “%” for some reason, compared to Perls’ “,”.
    1
    
    print "some string: %s" % str1
  • One can do something like
    1
    
    a, b, c = x

    if x is a sequence of 3 items. This would assign a, b, and cy to the items of x, respectively. In Perl, similarly, you could do

    1
    
    ($a, $b, $c) = @x
  • A shortcut for string repetition is
    1
    
    print str1 * 10

    vs Perl's

    1
    
    print $str1 x 10

Chapter 2.

  • Here we go: conditional statements if, elif, and else. This is what I’ve been waiting for – as there are no braces needed around conditional statements, loops, etc, indentation plays the role of controlling context. But for *****s sake, PHP has elseif, Perl has elsif, now elif? What’s next, eif? Anyway, a conditional statement is followed by a “:” and then an indented block of lines.
  • I like how I don’t need to put parentheses after if. This is similar to Perl’s notation where if comes after the main statement. However, parentheses are mandatory otherwise in Perl.
  • Loops have while and for. Where’s foreach? (panic… noooooooooooooooooooooooo!!! Perl spoiled me.) Actually, I was wrong. It’s exactly the opposite – Python’s for is exactly like Perl’s foreach (thanks Travis!). Rather, Python doesn’t have the c-style for. To break out of a loop, break is used (phew, at least this is expected) vs Perl’s last and to continue, continue is used vs Perl’s next.
  • Oh, so back to indentation again. Any inconsistent indentation is accompanied by an IndentationError (Inconsistent dedent in Pydev Eclipse) compile time error. I think I like this rule in general, because it encourages proper white space in the code but I have not decided yet. This makes me kind of worried – what if some code gets slightly scrambled and some spaces get lost, for example copy-pasting from a random Internet site or if my blog code displaying tools lose indentation. In Eclipse, a simple Ctrl-Shift-F, which runs Perltidy, can fix any indentation problems and inconsistencies. I don’t know Python, I don’t know…
  • This is interesting: a loop can have an else statement. If the loop does not end via break, the else statement triggers. I could see this usage for example: if I’m TODOlooking for something in a hash, you can break the else statement can print “Not found” and act on it.
  • Slicing multiple consecutive values in lists is done via “:” rather than Perl’s “..”. Compare list[1:3] vs Perl’s @list[1..3]. . What's interesting is an optional 3rd parameter to the slice, which specifies a stride. Thus, list[::2] would produce a sequence with items that have an even index in list and list[::-1] would reverse the list. Quite handy and original.
  • if no action is performed by something that requires a level of indentation (for example, an if statement that does nothing), a special keyword pass needs to be used. In Perl, it would just be an empty set of parentheses.
    1
    2
    3
    4
    
    if some_event_that_needs_no_action:
      pass
    else:
      # do stuff

Chapter 3.

  • Python seems to have proper exception handling support. A breath of fresh air from Perl’s hacky evals. Try with try, catch with except, and finally with finally. What is the generic Error name that you can use to catch all errors?
  • One can raise an error by using a raise keyword.

Chapter 4.

  • Functions are defined using the def keyword, as opposed to Perl’s sub.
  • Function documentation (docstring) is simply a string that follows the function definition. It is what intellisense-enabled IDEs use (and probably some sort of python documenters). This information is also available as function_name.__doc__. I really like this as I think Perl’s POD style is hideous. I’ll have to see how powerful this docstring can get, because perlpod, though hideous, supports a variety of formatting options.
  • dir(object) shows all properties of object. I’m guessing this is another way intellisense IDEs get the information to show a user. For example,
    1
    2
    3
    
    >>> dir(my_func)
    ['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__getattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__',
    '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
  • A function can have default parameters, similar to PHP. Perl 5 doesn’t have such construct, it’s only introduced in Perl 6. For example
    1
    
    def do_search(string, start = "."):
  • A function can be defined within another function and will only be available in the latter’s scope. I am fairly sure Perl allows you to do the same, though I see this functionality as very insignificant.
  • type() allows one to determine the type of a variable. For instance, to see if a variable is a dictionary
    1
    
    if type(dict) == type({}):

Chapter 5.

  • A class is defined using a keyword class vs Perl’s package. Talking about Perl’s class implementation causes vomiting reaction in me, and I’m really hoping Python’s is better. Python is supposed to be a proper OO language and that is partly why I’m learning it. However, one thing is upsettingly common between Python and Perl and that is self in Python and $self in Perl are the first parameters in class member functions, rather than being implied, like in C++ or PHP. So one has to write def add(self, num_list) rather than def add(num_list). Is it because Python is so OO to the bone that it has to have everything declared and nothing implied?
  • At first sight, a few things are kind of upsetting actually. The examples in the book don’t define member variables – they just assign them outside of the class definition. Whaaaat? How is this different from Perl then?
  • A function is public by default. To make a function private, one needs to prefix it with __. However, if it also ends with __, it’s not private  but instead just considered internal (kind of like hidden but not really). An internal function is technically supposed to be used by member methods only but nothing prevents anyone outside the class definition to call it (see the __contains__() example in chapter 1). That’s a bit ambiguous to say the least but still better than Perl’s hacks related to private functions.
  • Python doesn’t support protected functions.
  • At this point I’m starting to read O’Reilly Python In A Nutshell in parallel with Wrox Beginning Python that I’ve been reading so far. It is much more concise and to the point. Wrox assumes I’m a total noob, even beyond noob. I highly recommend the O’Reilly book.

 

 

[WORK IN PROGRESS]

● ● ●
Artem Russakovskii is a San Francisco programmer and blogger. Follow Artem on Twitter (@ArtemR) or subscribe to the RSS feed.

In the meantime, if you found this article useful, feel free to buy me a cup of coffee below.