Softpanorama

Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
May the source be with you, but remember the KISS principle ;-)
Skepticism and critical thinking is not panacea, but can help to understand the world better

Python for Perl programmers

News  Python -- Scripting language with generators and coroutines.

Best Python books for system administrators

Recommended Links Perl to Python functions map Execution of commands and shell scripts using subprocess module Two-pass "fuzzy" compiler from Perl to Python
Perl to Python functions map Perl and Python string functions mapping Perl special variable mapping to Python Execution of commands and shell scripts using subprocess module Command-Line Syntax and Options Imitation of Perl double quoted strings in Python Chomp to string.rstrip
Python ternary conditional operator Imitation of Perl double quoted strings in Python Loops in Python Loop else Execution of commands and capturing output of shell scripts and pipelines  Comparison of Perl and Python string operations Functions
Python source code checking tools to help you find common bugs Python pretty printers          
Python Debugging pdb — The Python Debugger Python Braces Debate Programming environment Python IDEs Pycharm IDE Jython
Debugging in Python Algorithms Quotes Python history Python Cheatsheets Etc Tutorials

Introduction

There's no benefits to rewriting a ton of code from one similar language to another. This is especially stupid, if we are talking  about sysadmin utilities.  Perl 5 is here to stay and will not go anywhere.  Perl is much closer to shell, knowledge of which is a must for any sysadmin then Python.

But popularity of Python and its dominance in research create pressure for Perl programmers to learn Python. One way to do this is try to migrate some of utilities that can benefit from Python features (to example tuples) to Python, so that they can maintain them in Python, and  doing this learn the language.

Here the sweet dream of semi-automatic translation comes into  play. The author is trying to implement with his pythonizer tool a modest  but practical solution to this problems see Two-pass "fuzzy" transformer from Perl to "semi-Python"

Rewriting even medium complexity Perl script in Python, usually requires some level of redesign, as languages have different ways to express things and there is no direct mapping between functions and special variables from Perl to Python. Many simple Perl expressions (for example used for stripping leading or trailing blanks) can be rewritten with functions in Python. Also even if function exists there is no guarantee that it behaves the same way. For example, while $^O gives you operating  system in Perl as "linux" on linux and "cygwin" on  CygWin, Python  os.name gives you "posix" in both cases.  The same is true, for example, for Solaris. It also returns posix

Example of translation

Only simple scripts that use non OO subset of Perl5 can be semi-automatically translated.  Luckily, they constitute significant share of useful Perl scripts, especially small (less then 1K lines). By semi-automatically I means that you can automatically find close correspondence for approximately 80-90% of statements, and do the rest of conversion manually. In other words as the first step you can generate "Pythonized" Perl and then try to correct/transform remaining differences and problems by hand. This approach works well for the majority of monolithic simple ( non OO)  scripts. 

For non OO subset of Perl 5 there are also greater similarities with Python: a very similar precedence model for operators, access to a very similar set of basic data types – the familiar scalar, array, and hash are all available to us, albeit under different names. Regex are different, but basics of Perl regex are similar to Python re.match and re.matchall.  As soon as you encounter the script with Perl5 pointers or OO, the situation became close to hopeless and complete rewrite might be a better option  then semi-automated translation.

The test below shows the current capabilities of pythonizer. It  was run using the source of  pre_pythonizer.pl -- the script which was already posted on GitHub (see see pre_pythonizer.pl ):

  ... ... ... 
  59 | 0 |      |breakpoint=-1                                                            #Perl: $breakpoint=-1;
  60 | 0 |      |SCRIPT_NAME=sys.argv[0][sys.argv[0].rfind( '/')+1:]                      #Perl: $SCRIPT_NAME=substr($0,rindex($0,'/')+1);
  61 | 0 |      |dotpos=SCRIPT_NAME.find( '.')                                            #Perl: if( ($dotpos=index($SCRIPT_NAME,'.'))>-1 ) {
  61 | 0 |      |if dotpos>-1:
  62 | 1 |      |   SCRIPT_NAME=SCRIPT_NAME[0:dotpos]                                     #Perl: $SCRIPT_NAME=substr($SCRIPT_NAME,0,$dotpos);
  64 | 0 |      |
  65 | 0 |      |OS=os.name # $^O is built-in Perl variable that contains OS name         #Perl: $OS=$^O;
  66 | 0 |      |if OS== 'cygwin':                                                        #Perl: if($OS eq 'cygwin' ){
  67 | 1 |      |   HOME= "/cygdrive/f/_Scripts" # $HOME/Archive is used for backups      #Perl: $HOME="/cygdrive/f/_Scripts";
  68 | 0 |      |elif OS== 'linux':                                                       #Perl: }elsif($OS eq 'linux' ){
  69 | 1 |      |   HOME=ENV[ 'HOME'] # $HOME/Archive is used for backups                 #Perl: $HOME=ENV{'HOME'};
  71 | 0 |      |LOG_DIR= "/tmp/" + SCRIPT_NAME                                           #Perl: $LOG_DIR="/tmp/$SCRIPT_NAME";
  72 | 0 |      |
  73 | 0 |      |
  74 | 0 |      |tab=3                                                                    #Perl: $tab=3;
  75 | 0 |      |nest_corrections=0                                                       #Perl: $nest_corrections=0;
  76 | 0 |      |keyword={ 'if': 1, 'while': 1, 'unless': 1, 'until': 1, 'for': 1, 'foreach': 1, 'given': 1, 'when': 1, 'default': 1}
                                                                                          #Perl: %keyword=('if'=>1,'while'=>1,'unless'=>1, 'until'=>1,'for'=>1,'foreach'=
                                                                                          #Cont: >1,'given'=>1,'when'=>1,'default'=>1);
  77 | 0 |      |
  78 | 0 |      |logme([ 'D',1,2)]) # E and S to console, everything to the log.          #Perl: logme('D',1,2);
  79 | 0 |      |banner([LOG_DIR,SCRIPT_NAME, 'Phase 1 of pythonizer',30)]) # Opens SYSLOG and print STDERRs banner; parameter 4 is log retention period #Perl: banner($LOG_DIR,$SCRIPT_NAME,'Phase 1 of pythonizer',30);
  80 | 0 |      |get_params([)]) # At this point debug  flag can be reset                 #Perl: get_params();
  81 | 0 |      |if debug>0:                                                              #Perl: if( $debug>0 ){
  82 | 1 |      |   logme([ 'D',2,2)]) # Max verbosity                                    #Perl: logme('D',2,2);
  83 | 1 |      |   print >>sys.stderr "ATTENTION!!! " + SCRIPT_NAME + " is working in debugging mode " + debug + " with autocommit of source to " + HOME + "/Archive\n"
                                                                                          #Perl: print STDERR "ATTENTION!!! $SCRIPT_NAME is working in debugging mode $de
                                                                                          #Cont: bug with autocommit of source to $HOME/Archive\n";
  84 | 1 |      |   autocommit([HOME + "/Archive",use_git_repo)]) # commit source archive directory (which can be controlled by GIT) #Perl: autocommit("$HOME/Archive",$use_git_repo);
  86 | 0 |      |print >>sys.stderr "=" * 80, "\n\n"                                      #Perl: print STDERR  "=" x 80,"\n\n";
... ... ...
 100 | 0 |      |#
 101 | 0 |      |# MAIN LOOP
 102 | 0 |      |#
 103 | 0 |      |for lineno range(0,SourceText):                                          #Perl: for( $lineno=0; $lineno<@SourceText; $lineno++  ){
 104 | 1 |      |   line=SourceText[lineno]                                               #Perl: $line=$SourceText[$lineno];
 105 | 1 |      |   offset=0                                                              #Perl: $offset=0;
 106 | 1 |      |   line=line.rstrip("\n")                                                #Perl: chomp($line);
 107 | 1 |      |   intact_line=line                                                      #Perl: $intact_line=$line;
 108 | 1 |      |   if lineno==breakpoint:                                                #Perl: if( $lineno == $breakpoint ){
 109 | 2 | FAIL |      DB.single=1                                                        #Perl: $DB::single = 1
 111 | 1 |      |   line=line.translate(maketrans('\t',' ')) # eliminate \t               #Perl: $line=~tr/\t/ /;
 112 | 1 |      |   if line[-1:1]== "\r":                                                 #Perl: if( substr($line,-1,1) eq "\r" ){
 113 | 2 |      |      line=line[0:-1]                                                    #Perl: chop($line);
 115 | 1 |      |   # trip traling blanks, if any
 116 | 1 |      |   if line.re.match(r"(^.*\S)\s+$"):                                     #Perl: if( $line=~/(^.*\S)\s+$/ ){
 117 | 2 |      |      line=rematch.group(1)                                              #Perl: $line=$1;

 While only a small fragment is shown, the program was able to translate all the code. For full protocol see Full protocol of translation of pre_pythonizer.pl by version 0.07 of pythonizer

Troubles

Variables such as $_ (the result of operation, such as reading a line from a file) and $. (line number) gives a lot of troubles.   Python implements neither. So they need to be emulated. 

With mapping Perl functions to Python we also run into multiple problems. For example while string function index exists in Python as method in string class, its behaviour is different from behaviour of Perl index function. It raises exception  is substring is not found. You need to use a different string class methods find (and rfind) to imitate Perl behavior in which if substring is not found the function simply returns  -1. Left hand substring function does not has direct Python analogs and needs to be emulated iether via concatenation or via join function.  Similar situation exists with double quotes. And this is only the beginning of troubles with conversion from Perl to Python.     Generally the more rich subset of Perl is used, the lessee are chances that semiautomatic translation is useful. 

Several emulators of Perl features exist. for example fileinput.py that comes with  Standard Python distribution allow to iterate between all files supplied as the argument (implicit cat for the files), while glob.py allow to return list of files for given regular expression.  In addition, tempfile.py help to create temp files.

While having there own set of warts, Python avoids three major Perl pitfalls:

BTW Python 3  (and to a lesser extent Python 2.5+) supports coroutines, so a large Perl script might be broken into several "passes" to make it simpler.  That's a distinct advantage which allow to create more manageable programs.

Excessive zeal in conversion from Perl to Python can hurt

While we discuss the conversion of Perl to Python as something already decided, often it is better not to move to Python. Much  depends on the skillset available on the floor. Outside simple scripts a direct conversion of reasonably complex medium size script (over 1K=10K lines)  is a very complex task even for high level professional who devoted their professional career to studying programming languages, and wrote their own compliers.

A useful discussion can be found at  Conversion of Perl to Python page and for details) and often requires restructuring of the code.   If you need a small change in existing Perl code, usually correcting it directly is a better deal. Maybe adding use strict,  and running the script via perltidy. You might benefit from buying some books like Perl Cookbook, or talking to your co-workers.

If you plan to re-write existing, working Perl code because you're worried about Perl being not-quite-as-purely OO as Python,  then there is no help.  You need to pay the price. That's actually a good punishment for their folly ;-).  OO fundamentalists is the worst type of co-workers you can have in any case and the decision to occupy them with some semi-useless task is a good management decision.

The same is true for those who are worried about Perl obsolesce.  Please note that many people who predicted the demise of Fortran are already gone, but Fortran is here to stay.  This also can be a "programming fashion addicts" with the beta addicts mentality:  "Ooh! I found this cool new OO language and want to share its coolness with everyone by converting old scripts to it!"  Of course, programming is driven by fashion, much like woman clothing, but an excessive zeal in following fashion can cost you...

Learning Python typically requires forgetting Perl

Learning Python typically requires forgetting Perl: few programmers are able to write fluently in both languages as are they sufficiently similar and at the same time require different code practices.

Perl is more close to Unix culture. Python represent something like descendant of Nicklaus Wirth family of languages (Pascal, Modula, Modula 2). Or more correctly it is a direct descendant of ABC ( white space for indentation, if syntax if expression: syntax, etc)  with some Perl ideas incorporated in the process.

Most system administrators who know Perl are quite satisfied with it.  In Unix sysadmin domain Perl is slightly higher language then Python in a sense that you can write the same utility with less lines of code.  Those sysadmin usually started their small projects in Python in order to better understand the needs and problem that users which use Python as their primary (and often the only) programming language face.  This page is written for them.  I assume high to medium level of proficiency in Perl on this page.

Actually studying Python allow better understand strong points  of Perl. After using Python such thing that people generally do not value much like double quoted strings or integration of regular expression engine into the language now look in completely different light.

Some Perl idioms and constructs translated to Python

Tom Limoncelli in his post Python for Perl Programmers observed

There are certain Perl idioms that every Perl programmer uses: "while (<>) { foo; }" and "foo ~= s/old/new/g" both come to mind.

When I was learning Python I was pretty peeved that certain Python books don't get to that kind of thing until much later chapters. One didn't cover that kind of thing until the end! As [a long-time Perl user]( https://everythingsysadmin.com/2011/03/overheard-at-the-office-perl-e.html ) this annoyed and confused me.

While they might have been trying to send a message that Python has better ways to do those things, I think the real problem was that the audience for a general Python book is a lot bigger than the audience for a book for Perl people learning Python. Imagine how confusing it would be to a person learning their first programming language if their book started out comparing one language you didn't know to a different language you didn't know!

So here are the idioms I wish were in Chapter 1. I'll be updating this document as I think of new ones, but I'm trying to keep this to be a short list.

Processing every line in a file

Perl:

while (<>) {
    print $_;
}

Python:

for line in file('filename.txt'):
    print line

To emulate the Perl <> technique that reads every file on the command line or stdin if there is none:

import fileinput
for line in fileinput.input():
     print line

If you must access stdin directly, that is in the "sys" module:

import sys
for line in sys.stdin:
     print line

However, most Python programmers tend to just read the entire file into one huge string and process it that way. I feel funny doing that. Having used machines with very limited amounts of RAM, I tend to try to keep my file processing to a single line at a time. However, that method is going the way of the dodo.

contents = file('filename.txt').read()
all_input = sys.stdin.read()

If you want the file to be one string per line, with the newline removed just change read() to readlines()

list_of_strings = file('filename.txt').readlines()
all_input_as_list = sys.stdin.readlines()

Regular expressions

Python has a very powerful RE system, you just have to enable it with "import re". Any place you can use a regular expression you can also use a compiled regular expression. Python people tend to always compile their regular expressions; I guess they aren't used to writing throw-away scripts like in Perl:

import re
RE_DATE = re.compile(r'\d\d\d\d-\d{1,2}-\d{1,2}')
for line in sys.stdin:
     mo = re.search(RE_DATE, line)
     if mo:
          print mo.group(0)

There is re.search() and re.match(). re.match() only matches if the string starts with the regular expression. It is like putting a "^" at the front of your regex. re.search() is like putting a ".*" at the front of your regex. Since match comes before search alphabetically, most Perl users find "match" in the documentation, try to use it, and get confused that r'foo' does not match 'i foo you'. My advice? Pretend match doesn't exist (just kidding).

The big change you'll have to get used to is that the result of a match is an object, and you pull various bits of information from the object. If nothing is found, you don't get an object, you get None, which makes it easy to test for in a if/then. An object is always True, None is always false. Now that code above makes more sense, right?

Yes, you can put parenthesis around parts of the regular expression to extract out data. That's where the match object that gets returned is pretty cool:

import re
for line in sys.stdin:
     mo = re.search(r'(\d\d\d\d)-(\d{1,2})-(\d{1,2})', line)
     if mo:
          print mo.group(0)

The first thing you'll notice is that the "mo =" and the "if" are on separate lines. There is no "if x = re.search() then" idiom in Python like there is in Perl. It is annoying at first, but eventually I got used to it and now I appreciate that I can't accidentally assign a variable that I meant to compare.

Let's look at that match object that we assigned to the variable "mo" earlier:

The perl s// substitutions are easily done with re.sub() but if you don't require a regular expression "replace" is much faster:

>>> re.sub(r'\d\d+', r'', '1 22 333 4444 55555')
'1    '

>>> re.sub(r'\d+', r'', '9876 and 1234')
' and '

>>> re.sub(r'remove', r'', 'can you remove from')
'can you  from'

>>> 'can you remove from'.replace('remove', '')
'can you  from'

You can even do multiple parenthesis substitutions as you would expect:

>>> re.sub(r'(\d+) and (\d+)', r'yours=\1 mine=\2', '9876 and 1234')
'yours=9876 mine=1234'

After you get used to that, read the ""pydoc re" page":http://docs.python.org/library/re.html for more information.

String manipulations

I found it odd that Python folks don't use regular expressions as much as Perl people. At first I though this was due to the fact that Python makes it more cumbersome ('cause I didn't like to have to do 'import re'). It turns out that Python string handling can be more powerful. For example the common Perl idiom "s/foo/bar" (as long as "foo" is not a regex) is as simple as:

credit = 'i made this'
print credit.replace('made', 'created')

or

print 'i made this'.replace('made', 'created')

It is kind of fun that strings are objects that have methods. It looks funny at first.

Notice that replace returns a string. It doesn't modify the string. In fact, strings can not be modified, only created. Python cleans up for automatically, and it can't do that very easily if things change out from under it. This is very Lisp-like. This is odd at first but you get used to it. Wait... by "odd" I mean "totally fucking annoying". However, I assure you that eventually you'll see the benefits of string de-duplication and (I'm told) speed.

It does mean, however, that accumulating data in a string is painfully slow:

s = 'this is the first part\n'
s += 'i added this.\n'
s += 'and this.\n'
s += 'and then this.\n'

The above code is bad. Each assignment copies all the previous data just to make a new string. The more you accumulate, the more copying is needed. The Pythonic way is to accumulate a list of the strings and join them later.

s = []
s.append('this is the first part\n')
s.append('i added this.\n')
s.append('and this.\n')
s.append('and then this.\n')
print ''.join(s)

It seems slower, but it is actually faster. The strings stay in their place. Each addition to "s" is just adding a pointer to where the strings are in memory. You've essentially built up a linked list of pointers, which are much more light-weight and faster to manage than copying those strings around. At the end, you join the strings. Python makes one run through all the strings, copying them to a buffer, a pointer to which is sent to the "print" routine. This is about the same amount of work as Perl, which internally was copying the strings into a buffer along the way. Perl did copy-bytes, copy-bytes, copy-bytes, copy-bytes, pass pointer to print. Python did append-pointer 4 times then a highly optimized copy-bytes, copy-bytes, copy-bytes, copy-bytes, pass pointer to print.

joining and splitting.

This killed me until I got used to it. The join string is not a parameter to join but is a method of the string type.

Perl:

new = join('|', str1, str2, str3)

Python:

new = '|'.join([str1, str2, str3])

Python's join is a function of the delimiter string. It hurt my brain until I got used to it.

Oh, the join() function only takes one argument. What? It's joining a list of things... why does it take only one argument? Well, that one argument is a list. (see example above). I guess that makes the syntax more uniform.

Splitting strings is much more like Perl...

Kind of. The parameter is what you split on, or leave it blank for "awk-like splitting" (which heathens call "perl-like splitting" but they are forgetting their history).

Perl:

my @values = split('|', $data);

Python:

values = data.split('|');

You can split a string literal too. In this example we don't give split() any parameters so that it does "awk-like splitting".

print 'one two three four'.split()
['one', 'two', 'three', 'four']

If you have a multi-line string that you want to break into its individual lines, bigstring.splitlines() will do that for you.

Getting help

pydoc foo

except it doesn't work half the time because you need to know the module something is in . I prefer the "quick search" box on http://docs.python.org or "just use Google".

I have not read ""Python for Unix and Linux System Administration":http://www.amazon.com/dp/0596515820/safocus-20" but the table of contents looks excellent. I have read most of Python Cookbook (the first edition, there is a 2nd edition out too) and learned a lot. Both are from O'Reilly and can be read on Safari Books Online.

That's it!

That's it! Those few idioms make up most of the Perl code I usually wrote. Learning Python would have been so much easier if someone had showed me the Python equivalents early on.

One last thing... As a sysadmin there are a few modules that I've found useful:

See also


Top Visited
Switchboard
Latest
Past week
Past month

NEWS CONTENTS

Old News ;-)

[Nov 21, 2019] How to print to stderr in Python?

Nov 21, 2019 | stackoverflow.com

Ask Question Asked 8 years, 7 months ago Active 3 months ago Viewed 762k times 1239 170


Steve Howard ,Jul 31, 2013 at 14:05

There are several ways to write to stderr:
# Note: this first one does not work in Python 3
print >> sys.stderr, "spam"

sys.stderr.write("spam\n")

os.write(2, b"spam\n")

from __future__ import print_function
print("spam", file=sys.stderr)

That seems to contradict zen of Python #13 , so what's the difference here and are there any advantages or disadvantages to one way or the other? Which way should be used?

There should be one -- and preferably only one -- obvious way to do it.

Dan H ,May 16, 2017 at 22:51

I found this to be the only one short + flexible + portable + readable:
from __future__ import print_function
import sys

def eprint(*args, **kwargs):
    print(*args, file=sys.stderr, **kwargs)

The function eprint can be used in the same way as the standard print function:

>>> print("Test")
Test
>>> eprint("Test")
Test
>>> eprint("foo", "bar", "baz", sep="---")
foo---bar---baz

Dheeraj V.S. ,Jan 13, 2013 at 3:18

import sys
sys.stderr.write()

Is my choice, just more readable and saying exactly what you intend to do and portable across versions.

Edit: being 'pythonic' is a third thought to me over readability and performance... with these two things in mind, with python 80% of your code will be pythonic. list comprehension being the 'big thing' that isn't used as often (readability).

Michael Scheper ,Aug 26 at 17:01

print >> sys.stderr is gone in Python3. http://docs.python.org/3.0/whatsnew/3.0.html says:
Old: print >>sys.stderr, "fatal error"
New: print("fatal error", file=sys.stderr)

For many of us, it feels somewhat unnatural to relegate the destination to the end of the command. The alternative

sys.stderr.write("fatal error\n")

looks more object oriented, and elegantly goes from the generic to the specific. But note that write is not a 1:1 replacement for print .

luketparkinson ,Apr 23, 2013 at 10:04

For Python 2 my choice is: print >> sys.stderr, 'spam' Because you can simply print lists/dicts etc. without convert it to string. print >> sys.stderr, {'spam': 'spam'} instead of: sys.stderr.write(str({'spam': 'spam'}))

Mnebuerquo ,Jul 11 at 9:44

Nobody's mentioned logging yet, but logging was created specifically to communicate error messages. By default it is set up to write to stderr. This script:
# foo.py
import logging
logging.basicConfig(format='%(message)s')

logging.warning('I print to stderr by default')
logging.info('For this you must change the level and add a handler.')
print('hello world')

has the following result when run on the command line:

$ python3 foo.py > bar.txt
I print to stderr by default

(and bar.txt contains the 'hello world')

(Note, logging.warn has been deprecated , use logging.warning instead)

porgarmingduod ,Apr 15, 2016 at 1:37

I would say that your first approach:
print >> sys.stderr, 'spam'

is the "One . . . obvious way to do it" The others don't satisfy rule #1 ("Beautiful is better than ugly.")

Rebs ,Dec 30, 2013 at 2:26

I did the following using Python 3:
from sys import stderr

def print_err(*args, **kwargs):
    print(*args, file=stderr, **kwargs)

So now I'm able to add keyword arguments, for example, to avoid carriage return:

print_err("Error: end of the file reached. The word ", end='')
print_err(word, "was not found")

AMS ,Nov 5, 2015 at 14:15

This will mimic the standard print function but output on stderr
def print_err(*args):
    sys.stderr.write(' '.join(map(str,args)) + '\n')

Agi Hammerthief ,Dec 31, 2015 at 22:58

EDIT In hind-sight, I think the potential confusion with changing sys.stderr and not seeing the behaviour updated makes this answer not as good as just using a simple function as others have pointed out.

Using partial only saves you 1 line of code. The potential confusion is not worth saving 1 line of code.

original

To make it even easier, here's a version that uses 'partial', which is a big help in wrapping functions.

from __future__ import print_function
import sys
from functools import partial

error = partial(print, file=sys.stderr)

You then use it like so

error('An error occured!')

You can check that it's printing to stderr and not stdout by doing the following (over-riding code from http://coreygoldberg.blogspot.com.au/2009/05/python-redirect-or-turn-off-stdout-and.html ):

# over-ride stderr to prove that this function works.
class NullDevice():
    def write(self, s):
        pass
sys.stderr = NullDevice()

# we must import print error AFTER we've removed the null device because
# it has been assigned and will not be re-evaluated.
# assume error function is in print_error.py
from print_error import error

# no message should be printed
error("You won't see this error!")

The downside to this is partial assigns the value of sys.stderr to the wrapped function at the time of creation. Which means, if you redirect stderr later it won't affect this function. If you plan to redirect stderr, then use the **kwargs method mentioned by aaguirre on this page.

Florian Castellane ,Jan 8 at 6:57

In Python 3, one can just use print():
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)

almost out of the box:

import sys
print("Hello, world!", file=sys.stderr)

or:

from sys import stderr
print("Hello, world!", file=stderr)

This is straightforward and does not need to include anything besides sys.stderr .

phoenix ,Mar 2, 2016 at 23:57

The same applies to stdout:
print 'spam'
sys.stdout.write('spam\n')

As stated in the other answers, print offers a pretty interface that is often more convenient (e.g. for printing debug information), while write is faster and can also be more convenient when you have to format the output exactly in certain way. I would consider maintainability as well:

  1. You may later decide to switch between stdout/stderr and a regular file.
  2. print() syntax has changed in Python 3, so if you need to support both versions, write() might be better.

user1928764 ,Feb 10, 2016 at 2:29

I am working in python 3.4.3. I am cutting out a little typing that shows how I got here:
[18:19 jsilverman@JSILVERMAN-LT7 pexpect]$ python3
>>> import sys
>>> print("testing", file=sys.stderr)
testing
>>>
[18:19 jsilverman@JSILVERMAN-LT7 pexpect]$

Did it work? Try redirecting stderr to a file and see what happens:

[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ python3 2> /tmp/test.txt
>>> import sys
>>> print("testing", file=sys.stderr)
>>> [18:22 jsilverman@JSILVERMAN-LT7 pexpect]$
[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$ cat /tmp/test.txt
Python 3.4.3 (default, May  5 2015, 17:58:45)
[GCC 4.9.2] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
testing

[18:22 jsilverman@JSILVERMAN-LT7 pexpect]$

Well, aside from the fact that the little introduction that python gives you has been slurped into stderr (where else would it go?), it works.

hamish ,Oct 8, 2017 at 16:18

If you do a simple test:
import time
import sys

def run1(runs):
    x = 0
    cur = time.time()
    while x < runs:
        x += 1
        print >> sys.stderr, 'X'
    elapsed = (time.time()-cur)
    return elapsed

def run2(runs):
    x = 0
    cur = time.time()
    while x < runs:
        x += 1
        sys.stderr.write('X\n')
        sys.stderr.flush()
    elapsed = (time.time()-cur)
    return elapsed

def compare(runs):
    sum1, sum2 = 0, 0
    x = 0
    while x < runs:
        x += 1
        sum1 += run1(runs)
        sum2 += run2(runs)
    return sum1, sum2

if __name__ == '__main__':
    s1, s2 = compare(1000)
    print "Using (print >> sys.stderr, 'X'): %s" %(s1)
    print "Using (sys.stderr.write('X'),sys.stderr.flush()):%s" %(s2)
    print "Ratio: %f" %(float(s1) / float(s2))

You will find that sys.stderr.write() is consistently 1.81 times faster!

Vinay Kumar ,Jan 30, 2018 at 13:17

Answer to the question is : There are different way to print stderr in python but that depends on 1.) which python version we are using 2.) what exact output we want.

The differnce between print and stderr's write function: stderr : stderr (standard error) is pipe that is built into every UNIX/Linux system, when your program crashes and prints out debugging information (like a traceback in Python), it goes to the stderr pipe.

print : print is a wrapper that formats the inputs (the input is the space between argument and the newline at the end) and it then calls the write function of a given object, the given object by default is sys.stdout, but we can pass a file i.e we can print the input in a file also.

Python2: If we are using python2 then

>>> import sys
>>> print "hi"
hi
>>> print("hi")
hi
>>> print >> sys.stderr.write("hi")
hi

Python2 trailing comma has in Python3 become a parameter, so if we use trailing commas to avoid the newline after a print, this will in Python3 look like print('Text to print', end=' ') which is a syntax error under Python2.

http://python3porting.com/noconv.html

If we check same above sceario in python3:

>>> import sys
>>> print("hi")
hi

Under Python 2.6 there is a future import to make print into a function. So to avoid any syntax errors and other differences we should start any file where we use print() with from future import print_function. The future import only works under Python 2.6 and later, so for Python 2.5 and earlier you have two options. You can either convert the more complex print to something simpler, or you can use a separate print function that works under both Python2 and Python3.

>>> from __future__ import print_function
>>> 
>>> def printex(*args, **kwargs):
...     print(*args, file=sys.stderr, **kwargs)
... 
>>> printex("hii")
hii
>>>

Case: Point to be noted that sys.stderr.write() or sys.stdout.write() ( stdout (standard output) is a pipe that is built into every UNIX/Linux system) is not a replacement for print, but yes we can use it as a alternative in some case. Print is a wrapper which wraps the input with space and newline at the end and uses the write function to write. This is the reason sys.stderr.write() is faster.

Note: we can also trace and debugg using Logging

#test.py
import logging
logging.info('This is the existing protocol.')
FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s"
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning("Protocol problem: %s", "connection reset", extra=d)

https://docs.python.org/2/library/logging.html#logger-objects

[Nov 13, 2019] python - Running shell command and capturing the output

Nov 22, 2012 | stackoverflow.com

Vartec's answer doesn't read all lines, so I made a version that did:

def run_command(command):
    p = subprocess.Popen(command,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT)
    return iter(p.stdout.readline, b'')

Usage is the same as the accepted answer:

command = 'mysqladmin create test -uroot -pmysqladmin12'.split()
for line in run_command(command):
    print(line)
share python - Running shell command and capturing the output - Stack Overflow Share a link to this answer Copy link | improve this answer edited May 23 '17 at 11:33 Community ♦ 1 1 1 silver badge answered Oct 30 '12 at 9:24 Max Ekman Max Ekman 769 5 5 silver badges 5 5 bronze badges

[Nov 13, 2019] Execute shell commands in Python

Nov 13, 2019 | unix.stackexchange.com

Execute shell commands in Python Ask Question Asked 4 years ago Active 2 months ago Viewed 557k times 67 32


fooot ,Nov 8, 2017 at 21:39

I'm currently studying penetration testing and Python programming. I just want to know how I would go about executing a Linux command in Python. The commands I want to execute are:
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080

If I just use print in Python and run it in the terminal will it do the same as executing it as if you was typing it yourself and pressing Enter ?

binarysubstrate ,Feb 28 at 19:58

You can use os.system() , like this:
import os
os.system('ls')

Or in your case:

os.system('echo 1 > /proc/sys/net/ipv4/ip_forward')
os.system('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080')

Better yet, you can use subprocess's call, it is safer, more powerful and likely faster:

from subprocess import call
call('echo "I like potatos"', shell=True)

Or, without invoking shell:

call(['echo', 'I like potatos'])

If you want to capture the output, one way of doing it is like this:

import subprocess
cmd = ['echo', 'I like potatos']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

o, e = proc.communicate()

print('Output: ' + o.decode('ascii'))
print('Error: '  + e.decode('ascii'))
print('code: ' + str(proc.returncode))

I highly recommend setting a timeout in communicate , and also to capture the exceptions you can get when calling it. This is a very error-prone code, so you should expect errors to happen and handle them accordingly.

https://docs.python.org/3/library/subprocess.html

jordanm ,Oct 23, 2015 at 15:43

The first command simply writes to a file. You wouldn't execute that as a shell command because python can read and write to files without the help of a shell:
with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
    f.write("1")

The iptables command is something you may want to execute externally. The best way to do this is to use the subprocess module .

import subprocess
subprocess.check_call(['iptables', '-t', 'nat', '-A',
                       'PREROUTING', '-p', 'tcp', 
                       '--destination-port', '80',
                       '-j', 'REDIRECT', '--to-port', '8080'])

Note that this method also does not use a shell, which is unnecessary overhead.

Tom Hunt ,Oct 23, 2015 at 15:41

The quickest way:
import os
os.system("your command here")

This isn't the most flexible approach; if you need any more control over your process than "run it once, to completion, and block until it exits", then you should use the subprocess module instead.

jordanm ,Apr 5, 2018 at 9:23

As a general rule, you'd better use python bindings whenever possible (better Exception catching, among other advantages.)

For the echo command, it's obviously better to use python to write in the file as suggested in @jordanm's answer.

For the iptables command, maybe python-iptables ( PyPi page , GitHub page with description and doc ) would provide what you need (I didn't check your specific command).

This would make you depend on an external lib, so you have to weight the benefits. Using subprocess works, but if you want to use the output, you'll have to parse it yourself, and deal with output changes in future iptables versions.

,

A python version of your shell. Be careful, I haven't tested it.
from subprocess import run

def bash(command):
        run(command.split())

>>> bash('find / -name null')
/dev/null
/sys/fs/selinux/null
/sys/devices/virtual/mem/null
/sys/class/mem/null
/usr/lib/kbd/consoletrans/null

[Nov 11, 2019] Python Advanced Python and the Shell

Nov 11, 2019 | www.python-course.eu

Python and the Shell Shell Python and Shell Shell is a term, which is often used and often misunderstood. Like the shell of an egg, either hen or Python snake, or a mussel, the shell in computer science is generally seen as a piece of software that provides an interface for a user to some other software or the operating system. So the shell can be an interface between the operating system and the services of the kernel of this operating system. But a web browser or a program functioning as an email client can be seen as shell as well.

Understanding this, it's obvious that a shell can be either

But in most cases the term shell is used as a synonym for a command line interface (CLI). The best known and most often used shells under Linux and Unix are the Bourne-Shell, C-Shell or Bash shell. The Bourne shell (sh) was modelled after the Multics shell, and is the first Unix shell.
Most operating system shells can be used in both interactive and batch mode. System programming System programming (also known as systems programming) stands for the activity of programming system components or system software. System programming provides software or services to the computer hardware, while application programming produces software which provides tools or services for the user.

"System focused programming" as it is made possible with the aid of the sys and the os module, serves as an abstraction layer between the application, i.e. the Python script or program, and the operating system, e.g. Linux or Microsoft Windows. By means of the abstraction layer it is possible to implement platform independent applications in Python, even if they access operating specific functionalities.

Therefore Python is well suited for system programming, or even platform independent system programming. The general advantages of Python are valid in system focused programming as well:

The os Module The os module is the most important module for interacting with the operating system. The os module allows platform independent programming by providing abstract methods. Nevertheless it is also possible by using the system() and the exec*() function families to include system independent program parts. (Remark: The exec*()-Functions are introduced in detail in our chapter " Forks and Forking in Python ")
The os module provides various methods, e.g. the access to the file system. Executing Shell scripts with os.system() It's not possible in Python to read a character without having to type the return key as well. On the other hand this is very easy on the Bash shell. The Bash command " read -n 1 waits for a key (any key) to be typed. If you import os, it's easy to write a script providing getch() by using os.system() and the Bash shell. getch() waits just for one character to be typed without a return:
import os
def getch():
     os.system("bash -c \"read -n 1\"")
 
getch()
The script above works only under Linux. Under Windows you will have to import the module msvcrt. Pricipially we only have to import getch() from this module.
So this is the Windows solution of the problem:
from msvcrt import getch
The following script implements a platform independent solution to the problem:
import os, platform
if platform.system() == "Windows":
    import msvcrt
def getch():
    if platform.system() == "Linux":
        os.system("bash -c \"read -n 1\"")
    else:
        msvcrt.getch()

print("Type a key!")
getch()
print("Okay")
The previous script harbours a problem. You can't use the getch() function, if you are interested in the key which has been typed, because os.system() doesn't return the result of the called shell commands.
We show in the following script, how we can execute shell scripts and return the output of these scripts into python by using os.popen():
>>> import os
>>> dir = os.popen("ls").readlines()
>>> print dir
['curses.py\n', 'curses.pyc\n', 'errors.txt\n', 'getch.py\n', 'getch.pyc\n', 'more.py\n',
'numbers.txt\n', 'output.txt\n', 'redirecting_output.py\n', 'redirecting_stderr2.py\n', 
'redirecting_stderr.py\n', 'streams.py\n',  'test.txt\n']
>>>
The output of the shell script can be read line by line, as can be seen in the following example:
import os

command = " "
while (command != "exit"):
    command = raw_input("Command: ")
    handle = os.popen(command)
    line = " "
    while line:
        line = handle.read()
        print line
    handle.close()

print "Ciao that's it!"
subprocess Module The subprocess module is available since Python 2.4.
It's possible to create spawn processes with the module subprocess, connect to their input, output, and error pipes, and obtain their return codes.
The module subprocess was created to replace various other modules: Working with the subprocess Module Instead of using the system method of the os-Module
os.system('touch xyz')
we can use the Popen() command of the subprocess Module. By using Popen() we are capable to get the output of the script:
>>> x = subprocess.Popen(['touch', 'xyz'])
>>> print x

>>> x.poll()
0
>>> x.returncode
0
The shell command cp -r xyz abc can be send to the shell from Python by using the Popen() method of the subprocess-Module in the following way:
p = subprocess.Popen(['cp','-r', "xyz", "abc"])
There is no need to escape the Shell metacharacters like $, > usw..
If you want to emulate the behaviour of os.system, the optional parameter shell has to be set to true, i.e.
shell=True
and we have to use a string instead of a list:
p=subprocess.Popen("cp -r xyz abc", shell=True)

As we have said above, it is also possible to catch the output from the shell command or shell script into Python. To do this, we have to set the optional parameter stdout of Popen() to subprocess.PIPE:
>>> process = subprocess.Popen(['ls','-l'], stdout=subprocess.PIPE)
>>> print process.stdout.read()
total 132
-rw-r--r-- 1 bernd bernd   0 2010-10-06 10:03 abc
-rw-r--r-- 1 bernd bernd   0 2010-10-06 10:04 abcd
-rw-r--r-- 1 bernd bernd 660 2010-09-30 21:34 curses.py

If a shell command or shell script has been started with Popen(), the Python script doesn't wait until the shell command or shell script is finished. To wait until it is finished, you have to use the wait() method:

>>> process = subprocess.Popen(['ls','-l'], stdout=subprocess.PIPE)
>>> process.wait()
0
Functions to manipulate paths, files and directories
Function Description
getcwd() returns a string with the path of the current working directory
chdir(path) Change the current working directory to path.
Example under Windows:
>>> os.chdir("c:\Windows")
>>> os.getcwd()
'c:\\Windows'
An similiar example under Linux:
>>> import os
>>> os.getcwd()
'/home/homer'
>>> os.chdir("/home/lisa")
>>> os.getcwd()
'/home/lisa'
>>>
getcwdu() like getcwd() but unicode as output
listdir(path) A list with the content of the directory defined by "path", i.e. subdirectories and file names.
>>> os.listdir("/home/homer")
['.gnome2', '.pulse', '.gconf', '.gconfd', '.beagle', '.gnome2_private', '.gksu.lock', 'Public', '.ICEauthority', '.bash_history', '.compiz', '.gvfs', '.update-notifier', '.cache', 'Desktop', 'Videos', '.profile', '.config', '.esd_auth', '.viminfo', '.sudo_as_admin_successful', 'mbox', '.xsession-errors', '.bashrc', 'Music', '.dbus', '.local', '.gstreamer-0.10', 'Documents', '.gtk-bookmarks', 'Downloads', 'Pictures', '.pulse-cookie', '.nautilus', 'examples.desktop', 'Templates', '.bash_logout']
>>>
mkdir(path[, mode=0755]) Create a directory named path with numeric mode "mode", if it doesn't already exist. The default mode is 0777 (octal). On some systems, mode is ignored. If it is used, the current umask value is first masked out. If the directory already exists, OSError is raised. Parent directories will not be created, if they don't exist.
makedirs(name[, mode=511]) Recursive directory creation function. Like mkdir(), but makes all intermediate-level directories needed to contain the leaf directory. Raises an error exception if the leaf directory already exists or cannot be created.
rename(old, new) The file or directory "old" is renamed to "new" If "new" is a directory, an error will be raised. On Unix and Linux, if "new" exists and is a file, it will be replaced silently if the user has permission to do so.
renames(old, new) Works like rename(), except that it creates recursively any intermediate directories needed to make the "new" pathname.
rmdir(path) remove (delete) the directory "path". rmdir() works only, if the direcotry "path" is empty, otherwise an error is raised. To remove whole directory trees, shutil.rmdtree() can be used.

Further function and methods working on files and directories can be found in the module shutil. Amongst other possibilities it provides the possibility to copy files and directories with shutil.copyfile(src,dst).

Previous Chapter: Introduction into the sys module
Next Chapter: Forks and Forking in Python

[Nov 11, 2019] Python system command

Nov 11, 2019 | www.journaldev.com

In this tutorial we will learn about Python System Command. Previously we learned about Python Random Number .

Table of Contents [ hide ]

Python System Command

While making a program in python, you may need to exeucte some shell commands for your program. For example, if you use Pycharm IDE, you may notice that there is option to share your project on github. And you probably know that file transferring is done by git , which is operated using command line. So, Pycharm executes some shell commands in background to do it.

However, In this tutorial we will learn some basics about executing shell commands from your python code.

Python os.system() function

We can execute system command by using os.system() function. According to the official document, it has been said that

This is implemented by calling the Standard C function system(), and has the same limitations.

However, if command generates any output, it is sent to the interpreter standard output stream. Using this command is not recommended. In the following code we will try to know the version of git using the system command git --version .

import os cmd = "git --version" returned_value = os.system(cmd) # returns the exit code in unix print('returned value:', returned_value)

The following output found in ubuntu 16.04 where git is installed already.

git version 2 .14.2 returned value : 0

Notice that we are not printing the git version command output to console, it's being printed because console is the standard output stream here.

Python subprocess.call() Function

In the previous section, we saw that os.system() function works fine. But it's not recommended way to execute shell commands. We will use Python subprocess module to execute system commands.

We can run shell commands by using subprocess.call() function. See the following code which is equivalent to the previous code.

import subprocess cmd = "git --version" returned_value = subprocess.call(cmd, shell=True) # returns the exit code in unix print('returned value:', returned_value)

And the output will be same also.
Python System Command

Python subprocess.check_output() function

So far, we executed the system commands with the help of python. But we could not manipulate the output produced by those commands. Using subprocess.check_output() function we can store the output in a variable.

import subprocess cmd = "date" # returns output as byte string returned_output = subprocess.check_output(cmd) # using decode() function to convert byte string to string print('Current date is:', returned_output.decode( "utf-8" ))

It will produce output like the following

Current date is : Thu Oct 5 16 :31:41 IST 2017

So, in the above sections we have discussed about basic ideas about executing python system command. But there is no limit in learning. If you wish, you can learn more about Python System command using subprocess module from official documentation .

[Nov 11, 2019] python - How to access environment variable values

Nov 11, 2019 | stackoverflow.com
Environment variables are accessed through os.environ
import os
print(os.environ['HOME'])

Or you can see a list of all the environment variables using:

os.environ

As sometimes you might need to see a complete list!

# using get will return `None` if a key is not present rather than raise a `KeyError`
print(os.environ.get('KEY_THAT_MIGHT_EXIST'))

# os.getenv is equivalent, and can also give a default value instead of `None`
print(os.getenv('KEY_THAT_MIGHT_EXIST', default_value))

Python default installation on Windows is C:\Python . If you want to find out while running python you can do:

import sys
print(sys.prefix)

,

import sys
print sys.argv[0]

This will print foo.py for python foo.py , dir/foo.py for python dir/foo.py , etc. It's the first argument to python . (Note that after py2exe it would be foo.exe .)

[Nov 11, 2019] How can I find the current OS in Python

Nov 11, 2019 | stackoverflow.com

> ,May 29, 2012 at 21:57

Possible Duplicate:
Python: What OS am I running on?

As the title says, how can I find the current operating system in python?

Shital Shah ,Sep 23 at 23:34

I usually use sys.platform ( docs ) to get the platform. sys.platform will distinguish between linux, other unixes, and OS X, while os.name is " posix " for all of them.

For much more detailed information, use the platform module . This has cross-platform functions that will give you information on the machine architecture, OS and OS version, version of Python, etc. Also it has os-specific functions to get things like the particular linux distribution.

xssChauhan ,Sep 9 at 7:34

If you want user readable data but still detailed, you can use platform.platform()
>>> import platform
>>> platform.platform()
'Linux-3.3.0-8.fc16.x86_64-x86_64-with-fedora-16-Verne'

platform also has some other useful methods:

>>> platform.system()
'Windows'
>>> platform.release()
'XP'
>>> platform.version()
'5.1.2600'

Here's a few different possible calls you can make to identify where you are

import platform
import sys

def linux_distribution():
  try:
    return platform.linux_distribution()
  except:
    return "N/A"

print("""Python version: %s
dist: %s
linux_distribution: %s
system: %s
machine: %s
platform: %s
uname: %s
version: %s
mac_ver: %s
""" % (
sys.version.split('\n'),
str(platform.dist()),
linux_distribution(),
platform.system(),
platform.machine(),
platform.platform(),
platform.uname(),
platform.version(),
platform.mac_ver(),))

The outputs of this script ran on a few different systems (Linux, Windows, Solaris, MacOS) and architectures (x86, x64, Itanium, power pc, sparc) is available here: https://github.com/hpcugent/easybuild/wiki/OS_flavor_name_version

Steg ,Mar 31, 2015 at 15:13

import os
print os.name

This gives you the essential information you will usually need. To distinguish between, say, different editions of Windows, you will have to use a platform-specific method.

UnkwnTech ,Sep 21, 2008 at 6:17

https://docs.python.org/library/os.html

To complement Greg's post, if you're on a posix system, which includes MacOS, Linux, Unix, etc. you can use os.uname() to get a better feel for what kind of system it is.

> ,

Something along the lines:
import os
if (os.name == "posix"):
    print os.system("uname -a")
# insert other possible OSes here
# ...
else:
    print "unknown OS"

[Nov 11, 2019] Python read file from current line

Nov 11, 2019 | stackoverflow.com

Ask Question Asked 6 years, 8 months ago Active 6 years, 8 months ago Viewed 2k times 0


dylanoo ,Feb 18, 2013 at 17:09

I have one problem regarding using python to process the trace file (it contains billion lines of data).

What I want to do is, the program will find one specific line in the file (say it is line# x), and it needs to find another symbol from this (line# x) in the file. Once it finds the line, starts from (line# x) again to search another one.

What I did now, is as following, but the problem is it always needs to reopen the file and read from the beginning to find the match ones (line # > x, and contain the symbol I want). For one big trace file, it takes too long to processing.

1.

    for line in file.readlines()
      i++ #update the line number
      if i > x:
          if (line.find()):

or:

   for i, line in enumerate(open(file)):
      if i > x:
          if ....

Anyone can give me one hint on better ideas?

Thanks

dylanoo ,Feb 18, 2013 at 20:24

If the file is otherwise stable, use fileobj.tell() to remember your position in the file, then next time use fileobj.seek(pos) to return to that same position in the file.

This only works if you do not use the fileobject as an iterator (no for line in fileobject) or next(fileobject) ) as that uses a read-ahead buffer that will obscure the exact position.

Instead, use:

for line in iter(fileobj.readline, ''):

to still use fileobj in an iteration context.

Martijn Pieters ♦ ,Feb 18, 2013 at 17:30

I suggest you use random access, and record where your line started. Something like:
index = []

fh = open(gash.txt)

for line in fh:
    if target in line:
        index.append(fh.tell() - len(line))

Then, when you want to recall the contents, use fh.seek(index[n]) .

A couple of "gotchas":

  1. Notice that the index position will not be the same as the line number. If you need the line number then maybe use a dictionary, with the line number as the key.
  2. On Windows, you will have to adjust the file position by -1. This is because the "\r" is stripped out and does not appear in the len(line) .

[Oct 22, 2019] Python for a Perl programmer

Oct 22, 2019 | stackoverflow.com

Ask Question Asked 9 years, 8 months ago Active 11 months ago Viewed 22k times 53 47


Hamish Grubijan ,Feb 17, 2010 at 17:56

I am an experienced Perl developer with some degree of experience and/or familiarity with other languages (working experience with C/C++, school experience with Java and Scheme, and passing familiarity with many others).

I might need to get some web work done in Python (most immediately, related to Google App Engine). As such, I'd like to ask SO overmind for good references on how to best learn Python for someone who's coming from Perl background (e.g. the emphasis would be on differences between the two and how to translate perl idiomatics into Python idiomatics, as opposed to generic Python references). Something also centered on Web development is even better. I'll take anything - articles, tutorials, books, sample apps?

Thanks!

FMc ,Dec 19, 2014 at 17:50

I've recently had to make a similar transition for work reasons, and it's been pretty painful. For better or worse, Python has a very different philosophy and way of working than Perl, and getting used to that can be frustrating. The things I've found most useful have been

Personally, I found Dive Into Python annoying and patronising, but it's freely available online, so you can form your own judgment on that.

Philip Durbin ,Feb 18, 2010 at 18:12

If you happen to be a fan of The Perl Cookbook , you might be interested in checking out PLEAC, the Programming Language Examples Alike Cookbook , specifically the section that shows the Perl Cookbook code translated into Python .

larley ,Feb 18, 2010 at 6:16

Being a hardcore Perl programmer, all I can say is DO NOT BUY O'Reilly's "Learning Python". It is nowhere NEAR as good as "Learning Perl", and there's no equivalent I know of to Larry Wall's "Programming Perl", which is simply unbeatable.

I've had the most success taking past Perl programs and translating them into Python, trying to make use of as many new techniques as possible.

Mike Graham ,Feb 17, 2010 at 18:02

Check out the official tutorial , which is actually pretty good. If you are interested in web development you should be ready at that point to jump right in to the documentation of the web framework you will be working with; Python has many to choose from, with zope, cherrypy, pylons, and werkzeug all having good reputations.

I would not try to search for things specifically meant to help you transition from Perl, which are not to be of as high of quality as references that can be useful for more people.

ghostdog74 ,Feb 18, 2010 at 1:17

This is the site you should really go to. There's a section called Getting Started which you should take a look. There are also recommendations on books. On top of that, you might also be interested in this on "idioms"

sateesh ,Feb 17, 2010 at 18:08

If what you are looking at is succinct, concise reference to python then the book Python Essential Reference might be helpful.

Robert P ,May 31, 2013 at 22:39

I wouldn't try to compare Perl and Python too much in order to learn Python, especially since you have working knowledge of other languages. If you are unfamiliar with OOP/Functional programming aspects and just looking to work procedurally like in Perl, start learning the Python language constructs / syntax and then do a couple examples. if you are making a switch to OO or functional style paradigms, I would read up on OO fundamentals first, then start on Python syntax and examples...so you have a sort of mental blueprint of how things can be constructed before you start working with the actual materials. this is just my humble opinion however..

[Oct 15, 2019] Perl to Python Function translation [closed]

Feb 01, 2014 | stackoverflow.com

Ask Question Asked 5 years, 8 months ago Active 5 years, 8 months ago Viewed 303 times -3


Jim Garrison ,Feb 1, 2014 at 22:24

I am trying to translate a Perl function into a Python function, but I am having trouble figuring out what some of the Perl to Python function equivalents.

Perl function:

sub reverse_hex {

 my $HEXDATE = shift;
 my @bytearry=();
 my $byte_cnt = 0;
 my $max_byte_cnt = 8;
 my $byte_offset = 0;
 while($byte_cnt < $max_byte_cnt) {
   my $tmp_str = substr($HEXDATE,$byte_offset,2);
    push(@bytearry,$tmp_str);
   $byte_cnt++;
   $byte_offset+=2;
 }
   return join('',reverse(@bytearry));
}

I am not sure what "push", "shift", and "substr" are doing here that would be the same in Python.

Any help will be much appreciated.

Kenosis ,Feb 1, 2014 at 22:17

The Perl subroutine seems rather complicated for what it does, viz., taking chunks of two chars at a time (the first 16 chars) from the sent string and then reverses it. Another Perl option is:
sub reverse_hex {
    return join '', reverse unpack 'A2' x 8, $_[0];
}

First, unpack here takes two characters at a time (eight times) and produces a list. That list is reverse d and join ed to produce the final string.

Here's a Python subroutine to accomplish this:

def reverse_hex(HEXDATE):
    hexVals = [HEXDATE[i:i + 2] for i in xrange(0, 16, 2)]
    reversedHexVals = hexVals[::-1]
    return ''.join(reversedHexVals)

The list comprehension produces eight elements of two characters each. [::-1] reverses the list's elements and the result is join ed and returned.

Hope this helps!

MikeMayer67 ,Feb 2, 2014 at 2:10

I realize that you are asking about the perl to python translation, but if you have any control over the perl, I would like to point out that this function is a lot more complicated than it needs to be.

The entire thing could be replaced with:

sub reverse_hex
{
  my $hexdate = shift;
  my @bytes = $hexdate =~ /../g;  # break $hexdate into array of character pairs
  return join '', reverse(@bytes);
}

Not only is this shorter, it is much easier to get your head around. Of course, if you have no control over the perl, you are stuck with what you were dealt.

[Oct 14, 2019] How to read entire text file in Python

Jan 05, 2018 | cmdlinetips.com

Often one might need to read the entire content of a text file (or flat file) at once in python. In this post, we showed an example of reading the whole file and reading a text file line by line. Here is another way to import the entire content of a text file.

1 2 3 4 5 6 7 8 # Open a file: file file = open ( 'my_text_file' ,mode = 'r' ) # read all lines at once all_of_it = file .read() # close the file file .close()

[Oct 13, 2019] What is the system function in python

Oct 13, 2019 | stackoverflow.com

what is the system function in python Ask Question Asked 9 years, 3 months ago Active 9 years, 3 months ago Viewed 6k times 1


Eva Feldman ,Jul 6, 2010 at 15:55

I want to play with system command in python . for example we have this function in perl : system("ls -la"); and its run ls -la what is the system function in python ? Thanks in Advance .

Felix Kling ,Jul 6, 2010 at 15:58

It is os.system :
import os
os.system('ls -la')

But this won't give you any output. So subprocess.check_output is probably more what you want:

>>> import subprocess
>>> subprocess.check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'

KLee1 ,Jul 6, 2010 at 16:00

import os
os.system("")

From here

> ,

In the os module there is os.system() .

But if you want to do more advanced things with subprocesses the subprocess module provides a higher level interface with more possibilities that is usually preferable.

[Sep 30, 2019] 7 File Handling Operations in Python Explained with Programming Examples

csestack.org

How to open the File in Python? You can use the same code as I have mentioned for creating a file. You can use the same code as I have mentioned for creating a file.

open("myFile.txt", "r") as fObj
How to Read File in Python? First, open the file in reading mode "r" and then read the content from the file. First, open the file in reading mode "r" and then read the content from the file.
1 2 3 open ( "myFile.txt" ) as fObj data = fObj.read() print (data)
All the file contents will be saved in a single string object. You can also use "with" statement with an open file. All the file contents will be saved in a single string object. You can also use "with" statement with an open file. You can also use "with" statement with an open file. You can also use "with" statement with an open file.

with open ( "myFile.txt" ) as fObj: data = fObj.read() print (data)

There are multiple benefits of using "with" statement. We will see the benefits in the later part of this tutorial. Now a day it has become standard practice opening file "with" There are multiple benefits of using "with" statement. We will see the benefits in the later part of this tutorial. Now a day it has become standard practice opening file "with" Now a day it has become standard practice opening file "with" Now a day it has become standard practice opening file "with" How to Read Line-by-Line File into List? Rather than reading complete file text in a single string object, what if you want to read the file line-by-line? Rather than reading complete file text in a single string object, what if you want to read the file line-by-line?

with open ( "myFile.txt" ) as fObj: liData = fObj.readlines() print (liData)

Each line in the file will be saved as one element in the list. So the size of the list will be the same as the number of lines in the file. Reading file in the list is very important when you want to manipulate the text in each line of the file. After reading file content in the list, you just need to loop over each element in the list and perform your desired operation. Python provides Each line in the file will be saved as one element in the list. So the size of the list will be the same as the number of lines in the file. Reading file in the list is very important when you want to manipulate the text in each line of the file. After reading file content in the list, you just need to loop over each element in the list and perform your desired operation. Python provides Reading file in the list is very important when you want to manipulate the text in each line of the file. After reading file content in the list, you just need to loop over each element in the list and perform your desired operation. Python provides Reading file in the list is very important when you want to manipulate the text in each line of the file. After reading file content in the list, you just need to loop over each element in the list and perform your desired operation. Python provides Python provides Python provides multiple list operations which makes your work associated with the file operation even easier. How to Write a File in Python? Two operations. First, open the file and then write the text content in it. File object has write() method associated with it to write the text in the file. Two operations. First, open the file and then write the text content in it. File object has write() method associated with it to write the text in the file. File object has write() method associated with it to write the text in the file. File object has write() method associated with it to write the text in the file.

with open ( "myFile.txt" , 'a+' ) as fOut: fOut.write( "my data to add." + '\n' )

Here, Here,

... ... ..

[Sep 30, 2019] python - Delete a file or folder

Sep 30, 2019 | stackoverflow.com

Zygimantas ,Aug 9, 2011 at 13:05

How to delete a file or folder in Python?

Lu55 ,Jul 10, 2018 at 13:52

os.remove() removes a file.

os.rmdir() removes an empty directory.

shutil.rmtree() deletes a directory and all its contents.


Path objects from the Python 3.4+ pathlib module also expose these instance methods:

Éric Araujo ,May 22 at 21:37

Python syntax to delete a file
import os
os.remove("/tmp/<file_name>.txt")

Or

import os
os.unlink("/tmp/<file_name>.txt")
Best practice
  1. First, check whether the file or folder exists or not then only delete that file. This can be achieved in two ways :
    a. os.path.isfile("/path/to/file")
    b. Use exception handling.

EXAMPLE for os.path.isfile

#!/usr/bin/python
import os
myfile="/tmp/foo.txt"

## If file exists, delete it ##
if os.path.isfile(myfile):
    os.remove(myfile)
else:    ## Show an error ##
    print("Error: %s file not found" % myfile)
Exception Handling
#!/usr/bin/python
import os

## Get input ##
myfile= raw_input("Enter file name to delete: ")

## Try to delete the file ##
try:
    os.remove(myfile)
except OSError as e:  ## if failed, report it back to the user ##
    print ("Error: %s - %s." % (e.filename, e.strerror))
RESPECTIVE OUTPUT
Enter file name to delete : demo.txt
Error: demo.txt - No such file or directory.

Enter file name to delete : rrr.txt
Error: rrr.txt - Operation not permitted.

Enter file name to delete : foo.txt
Python syntax to delete a folder
shutil.rmtree()

Example for shutil.rmtree()

#!/usr/bin/python
import os
import sys
import shutil

# Get directory name
mydir= raw_input("Enter directory name: ")

## Try to remove tree; if failed show an error using try...except on screen
try:
    shutil.rmtree(mydir)
except OSError as e:
    print ("Error: %s - %s." % (e.filename, e.strerror))

Paebbels ,Apr 25, 2016 at 19:38

Use
shutil.rmtree(path[, ignore_errors[, onerror]])

(See complete documentation on shutil ) and/or

os.remove

and

os.rmdir

(Complete documentation on os .)

Kaz ,Sep 8, 2018 at 22:37

Create a function for you guys.
def remove(path):
    """ param <path> could either be relative or absolute. """
    if os.path.isfile(path):
        os.remove(path)  # remove the file
    elif os.path.isdir(path):
        shutil.rmtree(path)  # remove dir and all contains
    else:
        raise ValueError("file {} is not a file or dir.".format(path))

[Sep 30, 2019] Python File I-O Read and Write Files in Python

Sep 30, 2019 | www.programiz.com

Python File I/O In this article, you'll learn about Python file operations. More specifically, opening a file, reading from it, writing into it, closing it and various file methods you should be aware of. What is a file?

File is a named location on disk to store related information. It is used to permanently store data in a non-volatile memory (e.g. hard disk).

Since, random access memory (RAM) is volatile which loses its data when computer is turned off, we use files for future use of the data.

When we want to read from or write to a file we need to open it first. When we are done, it needs to be closed, so that resources that are tied with the file are freed.

Hence, in Python, a file operation takes place in the following order.

  1. Open a file
  2. Read or write (perform operation)
  3. Close the file

How to open a file?

Python has a built-in function open() to open a file. This function returns a file object, also called a handle, as it is used to read or modify the file accordingly.

  1. >>> f = open ( "test.txt" ) # open file in current directory
  2. >>> f = open ( "C:/Python33/README.txt" ) # specifying full path

We can specify the mode while opening a file. In mode, we specify whether we want to read 'r' , write 'w' or append 'a' to the file. We also specify if we want to open the file in text mode or binary mode.

The default is reading in text mode. In this mode, we get strings when reading from the file.

On the other hand, binary mode returns bytes and this is the mode to be used when dealing with non-text files like image or exe files.

Python File Modes
Mode Description
'r' Open a file for reading. (default)
'w' Open a file for writing. Creates a new file if it does not exist or truncates the file if it exists.
'x' Open a file for exclusive creation. If the file already exists, the operation fails.
'a' Open for appending at the end of the file without truncating it. Creates a new file if it does not exist.
't' Open in text mode. (default)
'b' Open in binary mode.
'+' Open a file for updating (reading and writing)
  1. f = open ( "test.txt" ) # equivalent to 'r' or 'rt'
  2. f = open ( "test.txt" , 'w' ) # write in text mode
  3. f = open ( "img.bmp" , 'r+b' ) # read and write in binary mode

Unlike other languages, the character 'a' does not imply the number 97 until it is encoded using ASCII (or other equivalent encodings).

Moreover, the default encoding is platform dependent. In windows, it is 'cp1252' but 'utf-8' in Linux.

So, we must not also rely on the default encoding or else our code will behave differently in different platforms.

Hence, when working with files in text mode, it is highly recommended to specify the encoding type.

  1. f = open ( "test.txt" , mode = 'r' , encoding = 'utf-8' )

How to close a file Using Python?

When we are done with operations to the file, we need to properly close the file.

Closing a file will free up the resources that were tied with the file and is done using Python close() method.

Python has a garbage collector to clean up unreferenced objects but, we must not rely on it to close the file.

  1. f = open ( "test.txt" , encoding = 'utf-8' )
  2. # perform file operations
  3. f . close ()

This method is not entirely safe. If an exception occurs when we are performing some operation with the file, the code exits without closing the file.

A safer way is to use a try...finally block.

  1. try :
  2. f = open ( "test.txt" , encoding = 'utf-8' )
  3. # perform file operations
  4. finally :
  5. f . close ()

This way, we are guaranteed that the file is properly closed even if an exception is raised, causing program flow to stop.

The best way to do this is using the with statement. This ensures that the file is closed when the block inside with is exited.

We don't need to explicitly call the close() method. It is done internally.

  1. with open ( "test.txt" , encoding = 'utf-8' ) as f :
  2. # perform file operations

How to write to File Using Python?

In order to write into a file in Python, we need to open it in write 'w' , append 'a' or exclusive creation 'x' mode.

We need to be careful with the 'w' mode as it will overwrite into the file if it already exists. All previous data are erased.

Writing a string or sequence of bytes (for binary files) is done using write() method. This method returns the number of characters written to the file.

  1. with open ( "test.txt" , 'w' , encoding = 'utf-8' ) as f :
  2. f . write ( "my first file\n" )
  3. f . write ( "This file\n\n" )
  4. f . write ( "contains three lines\n" )

This program will create a new file named 'test.txt' if it does not exist. If it does exist, it is overwritten.

We must include the newline characters ourselves to distinguish different lines.


How to read files in Python?

To read a file in Python, we must open the file in reading mode.

There are various methods available for this purpose. We can use the read(size) method to read in size number of data. If size parameter is not specified, it reads and returns up to the end of the file.

  1. >>> f = open ( "test.txt" , 'r' , encoding = 'utf-8' )
  2. >>> f . read ( 4 ) # read the first 4 data
  3. 'This'
  4. >>> f . read ( 4 ) # read the next 4 data
  5. ' is '
  6. >>> f . read () # read in the rest till end of file
  7. 'my first file\nThis file\ncontains three lines\n'
  8. >>> f . read () # further reading returns empty sting
  9. ''

We can see that, the read() method returns newline as '\n' . Once the end of file is reached, we get empty string on further reading.

We can change our current file cursor (position) using the seek() method. Similarly, the tell() method returns our current position (in number of bytes).

  1. >>> f . tell () # get the current file position
  2. 56
  3. >>> f . seek ( 0 ) # bring file cursor to initial position
  4. 0
  5. >>> print ( f . read ()) # read the entire file
  6. This is my first file
  7. This file
  8. contains three lines

We can read a file line-by-line using a for loop . This is both efficient and fast.

  1. >>> for line in f :
  2. ... print ( line , end = '' )
  3. ...
  4. This is my first file
  5. This file
  6. contains three lines

The lines in file itself has a newline character '\n' .

Moreover, the print() end parameter to avoid two newlines when printing.

Alternately, we can use readline() method to read individual lines of a file. This method reads a file till the newline, including the newline character.

  1. >>> f . readline ()
  2. 'This is my first file\n'
  3. >>> f . readline ()
  4. 'This file\n'
  5. >>> f . readline ()
  6. 'contains three lines\n'
  7. >>> f . readline ()
  8. ''

Lastly, the readlines() method returns a list of remaining lines of the entire file. All these reading method return empty values when end of file (EOF) is reached.

  1. >>> f . readlines ()
  2. [ 'This is my first file\n' , 'This file\n' , 'contains three lines\n' ]

Python File Methods

There are various methods available with the file object. Some of them have been used in above examples.

Here is the complete list of methods in text mode with a brief description.

Python File Methods
Method Description
close() Close an open file. It has no effect if the file is already closed.
detach() Separate the underlying binary buffer from the TextIOBase and return it.
fileno() Return an integer number (file descriptor) of the file.
flush() Flush the write buffer of the file stream.
isatty() Return True if the file stream is interactive.
read( n ) Read atmost n characters form the file. Reads till end of file if it is negative or None .
readable() Returns True if the file stream can be read from.
readline( n =-1) Read and return one line from the file. Reads in at most n bytes if specified.
readlines( n =-1) Read and return a list of lines from the file. Reads in at most n bytes/characters if specified.
seek( offset , from = SEEK_SET ) Change the file position to offset bytes, in reference to from (start, current, end).
seekable() Returns True if the file stream supports random access.
tell() Returns the current file location.
truncate( size = None ) Resize the file stream to size bytes. If size is not specified, resize to current location.
writable() Returns True if the file stream can be written to.
write( s ) Write string s to the file and return the number of characters written.
writelines( lines ) Write a list of lines to the file.

[Sep 22, 2019] PerlPhrasebook -- Strings

wiki.python.org
Contents
    1. Introduction
    2. The obvious
    3. The not so obvious
    4. Simple types
      1. Strings
        1. Creating a string
        2. Quoting
        3. Interpolation
        4. Modifying a string
    5. Importing
    6. Common tasks
      1. Reading a file as a list of lines
      2. looping over files given on the command line or stdin
    7. Some general comparisons
    8. Lists of lists
      1. Lists of lists: preliminaries
        1. Lost in the translation
      2. requires/imports
      3. Declaration of a list of lists
      4. Generation of a list of lists
        1. Reading from a file line by line
        2. Reading from a file in one go
      5. Filling a list of lists with function calls
      6. Filling a list of lists with function calls, using temporaries
      7. Adding to an existing row in a list of lists
      8. Accessing elements of a list of lists
        1. One element
        2. Another element
      9. Printing a list of lists
        1. Print a list of lists using references
        2. Print a list of lists using indices
        3. Print a list of lists element by element
        4. Print a list of lists using map
        5. Print a list of lists using map and anonymous functions
    9. Hashes/dictionaries of lists
      1. Preliminaries
      2. Declaration of a hash of lists
      3. Initializing hashes of lists
        1. Initializing hashes of lists from a file
        2. Reading into a hash of lists from a file with temporaries
        3. Initializing a hash of lists from function calls
        4. Initializing a hash of lists from function calls with temporaries
      4. Append to a list in a hash of lists
      5. Access elements of a hash of lists
        1. Access a single element
        2. Change a single element
      6. Print a hash of lists
        1. Simple print
        2. Print with indices
        3. Print sorted by number of members
        4. Print sorted by number of members, and by name within each list
    10. Lists of hashes/dictionaries
      1. Lists of hashes: preliminaries
      2. Declaration of a list of hashes
      3. Generation of a list of hashes
        1. Reading a list of hashes from a file
        2. Reading a list of hashes from a file without temporaries
        3. Generation of a list of hashes from function calls
          1. Preliminaries
          2. Generation
          3. Generation without temporaries
      4. Adding a key/value pair to an element
      5. Accessing elements of a list of hashes
      6. Printing a list of hashes
        1. Simple print
        2. Print with indices
        3. Print whole thing one at a time
  1. Interface to the Tk GUI toolkit
    1. Preliminaries
    2. Hello world label
Introduction This phrasebook contains a collection of idioms, various ways of accomplishing common tasks, tricks and useful things to know, in Perl and Python side-by-side. I hope this will be useful for people switching from Perl to Python, and for people deciding which to choose. The first part of the phrasebook is based on Tom Christiansen's Perl Data Structures Cookbook . I have only been working on this for a short time, so many of the translations could probably be improved, and the format could be greatly cleaned up. I will get the data-structures cookbook translated first and then go back to clean up the code. Also, since I have been using Python for far less time than Perl, there are certainly idioms I don't know or that I will misuse. Please feel free to fix and update. -- Other references: PLEAC . -- Thanks to David Ascher, Guido van Rossum, Tom Christiansen, Larry Wall and Eric Daniel for helpful comments. -- TODO: QUESTIONS: The obvious Python don't need no steenking semicolons. The not so obvious There are many Integrated Development Environments, (IDEs), for Python that are usually recommended to new users and used by seasoned Python programmers alike. The Idle IDE is a TK based GUI providing language-aware editing, debugging and command line shell for Python that is part of the Python distribution. Many of the python examples shown can be experimented with in the Idle IDE. Simple types Strings Creating a string
$s = 'a string';
s = 'a string'
The $ in Perl indicates a scalar variable, which may hold a string, a number, or a reference. There's no such thing as a string variable in Python, where variables may only hold references. Quoting
$s1 = "some string";
$s2 = "a string with\ncontrol characters\n";
$s3 = 'a "quoted" string';
$s4 = "a 'quoted' string";
$s5 = qq/a string with '" both kinds of quotes/;
$s6 = "another string with '\" both kinds of quotes";
$s7 = 'a stri\ng that au\tomatically escapes backslashes';

foreach my $i ($s1, $s2, $s3, $s4, $s5, $s6, $s7)
{
  print "$i\n";
}
s1 = "some string"
s2 = "a string with\ncontrol characters\n"
s3 = 'a "quoted" string'
s4 = "a 'quoted' string"
s5 = '''a string with '" both kinds of quotes'''
s6 = "another string with '\" both kinds of quotes"
s7 = r"a stri\ng that au\tomatically escapes backslashes"

for i in (s1, s2, s3, s4, s5, s6, s7):
  print i
In both languages, strings can be single-quoted or double-quoted. In Python, there is no difference between the two except that in single- quoted strings double-quotes need not be escaped by doubling them, and vice versa. In Perl, double-quoted strings have control characters and variables interpolated inside them (see below) and single-quoted strings do not. Both languages provide other quoting mechanisms; Python uses triple quotes (single or double, makes no difference) for multi-line strings; Python has the r prefix ( r"some string" or r'some string' or r"""some string""" or r'''some string''' ) to indicate strings in which backslash is automatically escaped -- highly useful for regular expressions. Perl has very elaborate (and very useful) quoting mechanisms; see the operators q , qq , qw , qx , etc. in the PerlManual . Quoting is definitely one of the areas where Perl excels. Note that in Perl you can always replace foreach with for , which is shorter; but explicitly writing foreach is clearer, so you don't confuse it with the other kind of for . Interpolation
$name    = "Fred";
$header1 = "Dear $name,";
$title   = "Dr.";
$header2 = "Dear $title $name,";

print "$header1\n$header2\n";
name = "Fred"
header1 = "Dear %s," % name
title = "Dr."
header2 = "Dear %(title)s %(name)s," % vars()

print header1
print header2
Perl's interpolation is much more convenient, though slightly less powerful than Python's % operator. Remember that in Perl variables are interpolated within double-quoted strings, but not single-quoted strings. Perl has a function sprintf that uses the % conversion á la C; so the above lines could have been written:
$name    = "Fred";
$header1 = sprintf "Dear %s,", $name;
$title   = "Dr.";
$header2 = sprintf "Dear %s %s,", $name, $title;
Python's % (format) operator is generally the way to go when you have more than minimal string formatting to do (you can use + for concatenation, and [:] for slicing). It has three forms. In the first, there is a single % specifier in the string; the specifiers are roughly those of C's sprintf. The right-hand side of the format operator specifies the value to be used at that point:
x = 1.0/3.0
s = 'the value of x is roughly %.4f' % x
If you have several specifiers, you give the values in a list on the right hand side:
x = 1.0/3.0
y = 1.0/4.0
s = 'the value of x,y is roughly %.4f,%.4f' % (x, y)
Finally, you can give a name and a format specifier:
x = 1.0/3.0
y = 1.0/4.0
s = 'the value of x,y is roughly %(x).4f,%(y).4f' % vars()
The name in parentheses is used as a key into the dictionary you provide on the right-hand side; its value is formatted according to the specifier following the parentheses. Some useful dictionaries are locals() (the local symbol table), globals() (the global symbol table), and vars() (equivalent to locals() except when an argument is given, in which case it returns arg.__dict__ ). PEP215 proposed a $"$var" substitution mode as an alternative to "%(var)s" % locals() , but was rejected in favour of the explicit Template class proposed in PEP292 , which required no syntax changes. Modifying a string
$s1 = "new string";        # change to new string
$s2 = "new\nstring\with\nnew\nlines"; # change to new string
$s2 =~ s/\n/[newline]/g;   # substitute newlines with the text "[newline]"
$s2 = substr $s2, 0, 3,''; # extract the first 3 chars: "new"

print "$s1\n$s2\n";
s1 = "new string"          # change to new string
                           # substitute newlines with the text "[newline]"
s2 = s2.replace("\n", "[newline]")
s2 = s2[:3]

print s1
print s2
In Perl, strings are mutable; the third assignment modifies s2 . In Python, strings are immutable, so you have to do this operation a little differently, by slicing the string into the appropriate pieces. A Python string is just an array of characters, so all of the array operations are applicable to strings. In particular, if a is an array, a[x:y] is the slice of a from index x up to, but not including, index y . If x is omitted, the slice starts at the beginning of the array; if y is omitted, the slice ends at the last element. If either index is negative, the length of the array is added to it. So a[-4:] is the last four characters of a. In Perl, slicing is performed by giving the array a list of indices to be included in the slice. This list can be any arbitrary list and by using the range operator ... , you can get Python like slicing. If any of the indices in the list is out of bounds an undef is inserted there.
@array = ('zero', 'one', 'two', 'three', 'four')

# slicing with range operator to generate slice index list
@slice = @array[0..2]  # returns ('zero', 'one', 'two')

# Using arbitary index lists
@slice = @array[0,3,2] # returns ('zero', 'three', 'two')
@slice = @array[0,9,1] # returns ('zero', undef, 'one')
Note: Perl range operator uses a closed interval. To get the range to the end of the array, the last index must be used as
@a=(1,2,3,4,5);
$#a;           # last index, 4, because the firs index is 0 as in Python.
@a[ 2..$#a ]   # as Python's a[2:]
Importing In Perl a module is simply a package with a package name. ( see: perldoc -f package ). The symbols exported by the module depends on the module itself. The module may export symbols - mostly functions - by default, on request or none of them. In the latter case the module usually a class or has special access, like File::Spec. In Perl the module interfaces may vary - see the doc of the particular module.
use Module;  # imports module. It module exports symbols by default, those appeare in the package namespace.

use Module qw(symbol1 symbol2 symbol3); # preferred
or
use Module "symbol1";
from module import symbol1, symbol2, symbol3

# Allows mysymbol.func()
from module import symbol1 as mysymbol

# Unless the module is specifically designed for this kind of import, don't use it
from module import *

module.func()
Common tasks Reading a file as a list of lines
my $filename = "cooktest1.1-1";
open my $f, $filename or die "can't open $filename: $!\n";
@lines = <$f>;
filename = "cooktest1.1-1"
f = open(filename) # Python has exceptions with somewhat-easy to
                   # understand error messages. If the file could
                   # not be opened, it would say "No such file or
                   # directory: %filename" which is as
                   # understandable as "can't open $filename:"
lines = f.readlines()
In Perl, variables are always preceded by a symbol that indicates their type. A $ indicates a simple type (number, string or reference), an @ indicates an array, a % indicates a hash (dictionary). In Python, objects must be initialized before they are used, and the initialization determines the type. For example, a = [] creates an empty array a , d = {} creates an empty dictionary. looping over files given on the command line or stdin The useful Perl idiom of:
while (<>) {
    ...                 # code for each line
}
loops over each line of every file named on the commandline when executing the script; or, if no files are named, it will loop over every line of the standard input file descriptor. The Python fileinput module does a similar task:
import fileinput
for line in fileinput.input():
    ...                 # code to process each line
The fileinput module also allows inplace editing or editing with the creation of a backup of the files, and a different list of files can be given instead of taking the command line arguments. In more recent python versions, files can act as iterators, so you would just write:
for line in open(filename):
    ...                 # code to process each line
If you want to read from standard in, then use it as the filename:
import sys
for line in open(sys.stdin):
    ...                 # code to process each line
If you want to loop over several filenames given on the command line, then you could write an outer loop over the command line. (You might also choose to use the fileinput module as noted above).
import sys
for fname in sys.argv[1:]
    for line in open(fname):
        ...                 # code to process each line
Some general comparisons This section is under construction; for the moment I am just putting random notes here. I will organize them later. While most of the concerns are subjective here this one is obviously wrong. Perl has standard modules - eg. File::Spec -, and in general the module portability does not second to Python's. On the other hand, the CPAN - central module library - is a central module repository with elaborat interfaces. Lists of lists The Perl code in this section is taken, with permission, almost directly from Tom Christiansen's Perl Data Structures Cookbook , part 1, release 0.1, with a few typos fixed. Lists of lists: preliminaries
sub printSep { print "=" x 60, "\n" }

sub printLoL
{
  my ($s, $lol) = @_;
  print "$s\n";
  foreach my $l (@$lol) {
    print "@{$l}\n";
  }
  printSep();
}

# which is longhand for:
sub printLoL {
  print "$_[0]\n";
  print "@$_\n" foreach @{$_[1]};
  printSep();
}

# or even:
sub printLoL {
  print "$_[0]\n", map("@$_\n" , @{$_[1]}), "=" x 60, "\n";
}

# return numeric (or other) converted to string
sub somefunc { "". shift }
def printSep():
    print '=' * 60

def printLoL(s, lol):
    out = [s] + [" ".join(str(elem)) for elem in lol]
    print "\n".join(out)
    printSep()

def somefunc(i):
    return str(i)  # string representation of i
printLoL pretty-prints a list of lists. printSep prints a line of equal signs as a separator. somefunc is a function that is used in various places below. Lost in the translation In converting Perl examples so directly to Python, whilst initially useful, the casual browser should be aware that the task of printLoL is usually accomplished by just
  print lol
As Python can print default string representations of all objects. An import of the pprint at the beginning of a module would then allow
  pprint(lol)
to substitute for all cases of printLol in a more 'pythonic' way. ( pprint gives even more formatting options when printing data structures). requires/imports
import sys
Perl's use is roughly equivalent to Python's import . Perl has much more built in, so nothing here requires importing. For many simple operations, Perl will use a regular expression where Pythonic code won't. Should you really need to use regular expressions, import the re module. Declaration of a list of lists
@LoL = (
       [ "fred", "barney" ],
       [ "george", "jane", "elroy" ],
       [ "homer", "marge", "bart" ],
     );
@LoLsave = @LoL; # for later

printLoL 'Families:', \@LoL;
LoL = [["fred", "barney"],
       ["george", "jane", "elroy"],
       ["homer", "marge", "bart"]]
LoLsave = LoL[:] # See comment below

printLoL('Families:', LoL)
In Python, you are always dealing with references to objects. If you just assign one variable to another, e.g.,
a = [1, 2, 3]
b = a
you have just made b refer to the same array as a . Changing the values in b will affect a . Sometimes what you want is to make a copy of a list, so you can manipulate it without changing the original. In this case, you want to make a new list whose elements are copies of the elements of the original list. This is done with a full array slice --- the start of the range defaults to the beginning of the list and the end defaults to the end of the list, so
a = [1, 2, 3]
b = a[:]
makes a separate copy of a. Note that this is not necessarily the same thing as a deep copy, since references in the original array will be shared with references in the new array:
a = [ [1, 2, 3], [4, 5, 6] ]
b = a[:]
b[0][0] = 999
print a[0][0]   # prints 999
You can make a deep copy using the copy module:
import copy

a = [[1, 2, 3], [4, 5, 6]]
b = copy.deepcopy(a)
b[0][0] = 999
print a[0][0]   # prints 1
Generation of a list of lists Reading from a file line by line
open my $f, "cookbook.data1" or die $!;
my @LoL;
while (<$f>) {
  push @LoL, [ split ];
}
printLoL "read from a file: ", \@LoL;
LoL = []
for line in open('cookbook.data1'):
    LoL.append(line[:-1].split())
printLoL('read from a file: ', LoL)
Unless you expect to be reading huge files, or want feedback as you read the file, it is easier to slurp the file in in one go. In Perl, reading from a file-handle, e.g., <STDIN> , has a context-dependent effect. If the handle is read from in a scalar context, like $a = <STDIN>; , one line is read. If it is read in a list context, like @a = <STDIN>; the whole file is read, and the call evaluates to a list of the lines in the file. Reading from a file in one go
open my $f, "cookbook.data1" or die $!;
@LoL = map [split], <$f>;
printLoL "slurped from a file: ", \@LoL;
LoL = [line[:-1].split() for line in open('cookbook.data1')]
printLoL("slurped from a file: ", LoL)
Thanks to Adam Krolnik for help with the Perl syntax here. Filling a list of lists with function calls
foreach my $i ( 0 .. 9 ) {
    $LoL[$i] = [ somefunc $i ];
}
printLoL("filled with somefunc:", \@LoL);
LoL = [0] * 10  # populate the array -- see comment below

for i in range(10):
  LoL[i] = somefunc(i) # assuming that somefunc(i) returns the list that we want

printLoL('filled with somefunc:', LoL)
Or:
LoL = []

for i in range(10):
  LoL.append( somefunc(i) )

printLoL('filled with somefunc:', LoL)
Alternatively, you can use a list comprehension:
LoL = [somefunc(i) for i in range(10)]
printLoL('filled with somefunc:', LoL)
In python: Filling a list of lists with function calls, using temporaries
foreach my $i (0..9) {
    @tmp = somefunc $i;
    $LoL[$i] = [ @tmp ];
}

printLoL ("filled with somefunc via temps:", \@LoL);
for i in range(10):
    tmp = somefunc(i)
    LoL[i] = tmp

printLoL('filled with somefunc via temps:', LoL)
@LoL = map [ somefunc $_ ], 0..9;
printLoL 'filled with map', \@LoL;
LoL = map(lambda x: somefunc(x), range(10))
printLoL('filled with map', LoL)
Both Perl and Python allow you to map an operation over a list, or to loop through the list and apply the operation yourself. I don't believe it is advisable to choose one of these techniques to the exclusion of the other --- there are times when looping is more understandable, and times when mapping is. If conceptually the idea you want to express is "do this to each element of the list", I would recommend mapping because it expresses this precisely. If you want more precise control of the flow during this process, particularly for debugging, use loops. Tom Christiansen suggests that it is often better to make it clear that a function is being defined, by writing:
@LoL = map {[ somefunc($_) ]} 0..9;
rather than
@LoL = map [ somefunc($_) ], 0..9;
or
@LoL = map ([ somefunc($_)], 0..9);
Adding to an existing row in a list of lists
@LoL = @LoLsave;  # start afresh
push @{$LoL[0]}, "wilma", "betty";
printLoL ('after appending to first element:', \@LoL);
LoL = LoLsave[:]  # start afresh
LoL[0] += ["wilma", "betty"]
printLoL('after appending to first element:', LoL)
In python, the + operator is defined to mean concatenation for sequences. The + operator returns a new list object. Alternative to the above code that modify the original list object is to append each element of the list to LoL[0] :
LoL[0].append("wilma")
LoL[0].append("betty")
Or to extend:
LoL[0].extend(["wilma", "betty"])
Accessing elements of a list of lists One element
$LoL[0][0] = "Fred";
print ("first element is now $LoL[0][0]\n");
printSep();
LoL[0][0] = "Fred"
print 'first element is now', LoL[0][0]
printSep()
Another element
# upcase the first letter of each word
# s/(\w)/\u$1/ is almost equivalent to Python .capitalize() [.capitalize() also lowercases the remaining letters]

$LoL[1][1] =~ s{\b(\w)}{\u$1}g;
print ("element 1, 1 is now $LoL[1][1]\n");
printSep();
LoL[1][1] = LoL[1][1].title()
print 'element 1, 1 is now', LoL[1][1]
printSep()
Perl's regexp matching and substitution is enormously powerful; see especially the new syntax for comments and whitespace inside regular expressions. Python replaced its original regular expression module some years ago with one that closely matches the capabilities of Perls, including being able to do advanced RE tasks such as calling a function to provide the data for an RE substitution, and the optional inclusion of whitespace and comments in REs. In Python, string methods are often used where Perl would use a regex. Among these string methods are title() and capitalize() . In the context of names, title() will be used as it correctly changes "smith-jones" to "Smith-Jones" whereas capitalize() would produce "Smith-jones". str2 = str1.capitalize() in Python is equivalent to $str2 = ucfirst(lc($str1)) in Perl. Python's str2 = str1.title() is equivalent to Perl's:
$str2 = $str1;
$str2 =~ s{\b(\w)(\w*)\b}{\u$1\L$2\E}g;
This is because regular expression search and replace operations modify the string in place (Perl strings are mutable). Printing a list of lists Print a list of lists using references
foreach my $aref ( @LoL ) {
    print "\t [ @$aref ],\n";
}
printSep();
for a in LoL:
    print "\t [ %s ]," % a
printSep()
[Need a pointer to the % operator] Print a list of lists using indices
foreach my $i ( 0 .. $#LoL ) {
    print "\t [ @{$LoL[$i]} ],\n";
}
printSep();
for i in range(len(LoL)):
  print "\t [ %s ]," % LoL[i]
printSep()
The highest valid index of an array A : But note: The highest valid upper bound to a python range is len(A) as in
A[0:len(A)]
Size of an array A : Note: Perl does not really have a length operator like Python. scalar() simply provides a scalar context, and in a scalar context an array returns its size. (Perl is context-sensitive and things behave differently based on their context.) Generate range of numbers: Note: Perl uses a closed interval, while Python uses a closed-open interval. You will notice that this pattern is quite consistently applied in both languages. [Link to details of the range function] Print a list of lists element by element
foreach my $i ( 0 .. $#LoL ) {
    foreach my $j ( 0 .. $#{$LoL[$i]} ) {
        print "elt $i $j is $LoL[$i][$j]\n";
    }
}
printSep();
for i, mylist in enumerate(LoL):
    for j, elem in enumerate(mylist):
        print 'elt %d %d is %s' % (i, j, elem)
printSep()
Print a list of lists using map
sub printLine { print "@{shift()}\n" }
map printLine($_), @LoL;
printSep();
# This is legal but Do Not Do This
def printLine(l):
    print " ".join(l)
map(printLine, LoL)
printSep()
Print a list of lists using map and anonymous functions
print map "@$_\n", @LoL;
printSep();
# This is legal but Do Not Do This
map(lambda x: sys.stdout.write(" ".join(x)), LoL)
printSep()
The lack of true lambda expressions in Python is not really a problem, since all it means is that you have to provide a name for the function. Since you can define a function within another function, this does not lead to namespace clutter. In Perl, a function can be defined inside another function, but it is defined in the namespace of the current package. If you need Python-like scoping of functions, you can create an anonymous subroutine and assign it to a lexically scoped variable:
# A Python function with its own private function
def lolprint(LoL):
   # Private function
   def lprint(alist):
      print " ".join(str(alist))
   map(lprint, LoL)

# Achieving the same in Perl
sub lolprint {
   # Private function
   # (function reference stored in a lexically scoped variable)
   my $lprint = sub {
      my $list = shift;
      print "@$list";
   };
   map $lprint->($_), @_;
}

# In Perl, if you did this, the function is no longer private.
sub lolprint {
   # This is not a private function
   sub lprint {
      my $list = shift;
      print "@$list";
   };

   map lprint($_), @_;
}
Hashes/dictionaries of lists The Perl code in this section is taken, with permission, almost directly from Tom Christiansen's Perl Data Structures Cookbook , part 2, release 0.1, with a few typos fixed. Associative arrays are containers that hold pairs of elements. The first element of a pair is the key , the second is the value . In Python, the key may be of any type which is hashable (mutable data structures, like lists, sets, dictionaries, are no hashable). In Perl, the keys of a hash are converted into strings, which means if you try to use a reference as a key, it will get converted to some string representation, and you will not be able to use it as a reference anymore. Associative arrays are sometimes called maps, dictionaries (Python, Smalltalk), or hashes (Perl). Preliminaries
sub printSep { print "=" x 60, "\n" }

sub printHoL {
  my ($s, $hol) = @_;
  print "$s\n";
  foreach my $k (sort keys (%$hol))
  {
    my ($v) = $hol->{$k};
    print "$k: @$v\n";
  }
  printSep();
}

sub get_family {
  my ($group) = @_;
  $group =~ s/s$//;
  $group = "\u$group";
  return ("Mr-$group", "Mrs-$group", "$group-Jr");
}
def printSep():
    print '=' * 60

def printHoL(s, hol):
    print s
    for key, value in sorted(hol.items()):
        print key, ':', " ".join(value)
    printSep()

def get_family(group):
  group = group.title()
  return ["Mr-" + group, "Mrs-" + group, group + "-Jr"]
printHoL pretty-prints a hash/dictionary of lists. printSep prints a line of equal signs as a separator. get_family makes a list of names from a "group name", e.g., flintstones becomes [ "Mr-Flintstone", "Mrs-Flintstone", "Flintstone-Jr" ] This is for generating lists to fill a hash/dictionary. hol.items()` converts a dictionary to a list of (key, value) pairs, eg: [('flintstones', ['fred', 'barney']), ('jetsons', ['george', 'jane', 'elroy']), ('simpsons', ['homer', 'marge', 'bart'])] This list is then sorted (sorting is in-place in python) and then the pairs in the list are unpacked and used. If you didn't care for the results to be sorted (which is often true), you would simply do this:
sub printHoL {
  my ($s, $hol) = @_;
  print "$s\n";
  while (my ($k, $v) = each (%$hol))
  {
    print "$k: @$v\n")
  }
  printSep();
}
def printHoL(s, hol):
    print s
    for key, value in hol.items():
        print key, ':', " ".join(value)
    printSep()
Declaration of a hash of lists
%HoL = (
       flintstones        => [ "fred", "barney" ],
       jetsons            => [ "george", "jane", "elroy" ],
       simpsons           => [ "homer", "marge", "bart" ],
     );

printHoL 'names', \%HoL;
HoL = { 'flintstones' : ['fred', 'barney'],
        'jetsons' : ['george', 'jane', 'elroy'],
        'simpsons': ['homer', 'marge', 'bart'], }

printHoL('names', HoL)
In python, the print statement has very good default semantics --- most of the time, it does exactly what you want, putting a space between the arguments, and a newline at the end. If you want more control over the formatting, use the % operator [link to % operator]: rather than
print k, ':', " ".join(v)
you could use
print "%s: %s" % (k, " ".join(v))
to avoid the space before the colon. Note that both Perl and python let you have a comma after the last element of a list. This is especially useful for automatically generated lists, where you don't want to have to worry about a special case at the end. Larry Wall says:
$HoL = {
       flintstones => [ "fred", "barney" ],
       jetsons     => [ "george", "jane", "elroy" ],
       simpsons    => [ "homer", "marge", "bart" ],

};
printHoL (\'names\', $HoL);
Note that since $HoL is already a ref, the \\ is no longer necessary. Initializing hashes of lists Initializing hashes of lists from a file The file is assumed to consist of a sequence of lines of the form:
flintstones: fred barney wilma dino
my %HoL;
open my $f, "cookTest.2" or die $!;
while ( <$f> ) {
    next unless s/^(.*?):\s*//;
    $HoL{$1} = [ split ];
}
printHoL 'read from file cookTest.2', \%HoL;
HoL = {}
for line in open('cookTest.2'):
    try:
        surname, people = line.split(":", 1)
    except ValueError:             # can't split on ":" so no ":" in the line
        continue
    HoL[surname] = people.split()

printHoL('read from file cookTest.2', HoL)
Note that the Perl hash doesn't need to be initialized. Reading into a hash of lists from a file with temporaries
# flintstones: fred barney wilma dino
open my $f, "cookTest.3" or die $!;
my %HoL;
while ( defined(my $line = <$f>) ) {
    next unless $line =~ /:/;
    ($who, $rest) = split /:\s*/, $line, 2;
    @fields = split ' ', $rest;
    $HoL{$who} = [ @fields ];
}

printHoL 'read from cookTest.3', \%HoL;
HoL = {}
for line in open('cookTest.3'):
    try:
        n = line.index(":")
    except ValueError:         # ":" not found
        continue
    who, rest = line[:n], line[n+1:]  # n+1 skips the colon
    fields = rest.split()
    HoL[who] = fields

printHoL ('read from cookTest.3', HoL)
Initializing a hash of lists from function calls For each key of the hash, we call a function that creates a list, and associate the key with this list.
my %HoL;
foreach my $group (qw/simpsons jetsons flintstones/) {
    $HoL{$group} = [get_family $group];
}

printHoL 'filled by get_family', \%HoL;
HoL = {}
for group in ("simpsons", "jetsons", "flintstones"):
    HoL[group] = get_family(group)

printHoL ('filled by get_family', HoL)
The python section could [but should NOT] have been written:
HoL={}
def set(group, hol=HoL):
    hol[group] = get_family(group)
map(set, ("simpsons", "jetsons", "flintstones" ))

printHoL ('filled by get_family', HoL)
The Perl section could have been written:
my %Hol;
map {$HoL{$_} = [ get_family $_ ]} qw/simpsons jetsons flintstones/;
The Perl section could also have been written like this (each of the control statements, if , unless , while , until , foreach , etc., can be written as a "modifier" at the end of a statement):
my %HoL;
$HoL{$_} = [get_family $_] foreach (qw/simpsons jetsons flintstones/);
Initializing a hash of lists from function calls with temporaries For each key of the hash, we call a function that creates a list, and associate the key with this list. The list is assigned to a local variable (where it could be modified, for example).
my %HoL;
foreach my $group (qw/simpsons jetsons flintstones/) {
    my @members = get_family $group;
    $HoL{$group} = [@members];
}

printHoL 'by get_family with temps', \%HoL;
HoL = {}
for group in ("simpsons", "jetsons", "flintstones"):
    members = get_family(group)
    HoL[group] = members

printHoL ('by get_family with temps', HoL)
Append to a list in a hash of lists We want to add two strings to the list of strings indexed by the name flintstones .
push @{ $HoL{flintstones} }, "wilma", "betty";
print "@{$HoL{flintstones}}\n");
printSep();
HoL['flintstones'].extend(['wilma', 'betty'])
print " ".join(HoL['flintstones'])
printSep()
Note: There is a big difference between the above two examples, which create a new list, leaving the original list object unchanged; and the following two examples, which modify the original list.
HoL['flintstones'] += ['wilma', 'betty']
print " ".join(HoL['flintstones'])
printSep()
$HoL{'flintstones'} = [ @{ $HoL{'flintstones'} }, "wilma", "betty" ];
print "@{$HoL{flintstones}}\n");
printSep();
Access elements of a hash of lists Access a single element Assign to the first element of the list indexed by flintstones .
$HoL{flintstones}[0] = "Fred";
print $HoL{flintstones}[0], "\n";
printSep();
HoL['flintstones'][0] = "Fred"
print HoL['flintstones'][0]
printSep()
Tom Christiansen explains when you don't need quotes around strings in Perl: If blah were a function then you would have to use $something{blah()} to overwrite the stringificiation. Barewords are autoquoted in braces and as the LHS operand of =&rt; as well. Change a single element This upcases the first letter in the second element of the array indexed by simpsons . # another element
$HoL{simpsons}[1] =~ s/(\w)/\u$1/;

printHoL 'after modifying an element', \%HoL;
HoL['simpsons'][1] = HoL['simpsons'][1].title()

printHoL ('after modifying an element', HoL)
Print a hash of lists Various different ways of printing it out. Simple print Printed sorted by family name, in the format:
family1: member1-1 member1-2...
family2: member2-1 member2-2...
...
foreach my $family ( sort keys %HoL ) {
    print "$family: @{ $HoL{$family} }\n";
}
printSep();
families = sorted(HoL.items());
for surname, members in families:
    print '%s: %s' % (surname, " ".join(members))
printSep()
Print with indices
for my $family ( sort keys %HoL ) {
    print "family: ";
    for my $i ( 0 .. $#{ $HoL{$family}} ) {
        print " $i = $HoL{$family}[$i]";
    }
    print "\n";
}
printSep();
for surname in sorted(HoL.keys()):
    print 'surname: ',
    for i, member in enumerate(HoL[surname]):
        print '%d = %s' % (i, member),
    print
printSep()
Print sorted by number of members
push (@{$HoL{simpsons}}, 'Lisa');
for my $family ( sort { @{$HoL{$b}} <=> @{$HoL{$a}} } keys %HoL ) {
    print "$family: @{ $HoL{$family} }\n"
}
HoL['simpsons'] += ['Lisa']

def keyNumberMembers(x):
  return len(x[1])

families = HoL.items()
families.sort(key=keyNumberMembers)
for surname, members in families:
    print "%s:" % surname, " ".join(members)
You can use a lambda expression in python here, too, though I don't find it very readable:
HoL['simpsons'] += ['Lisa']
families = HoL.items()
families.sort(key=lambda x: len(x[1]))
for surname, members in k:
    print "%s:" % surname, " ".join(members))
Print sorted by number of members, and by name within each list
foreach my $family ( sort { @{$HoL{$b}} <=> @{$HoL{$a}} } keys %HoL ) {
    print "$family: @{[ sort @{ $HoL{$family}} ]}\n";
}
families = HoL.items()
families.sort(key=lambda x: len(x[1]))
for surname, members in families:
    members.sort()
    print "%s: %s" % (family, ", ".join(members))
Do it more like the Perl version:
for surname, members in sorted(HoL.items(), key=lambda x: len(x[1])):
   print "%s: %s" % (family, ", ".join(sorted(members)))
Lists of hashes/dictionaries The Perl code in this section is taken, with permission, almost directly from Tom Christiansen's Perl Data Structures Cookbook , part 3, release 0.1, with a few typos fixed. Lists of hashes: preliminaries
sub printSep { print "=" x 60, "\n" }

sub printLoH
{
  my ($s, $loh) = @_;
  print "$s\n";
  foreach my $h (@$loh)
  {
    print "[\n";
    foreach my $k (sort keys %$h)
    {
      print "  $k => $h->{$k}\n";
    }
    print "]\n";
  }
  printSep();
}
import sys

def printSep():
    print '=' * 60

def printLoH(s,loh):
    print s
    for h in loh:
        print "["
        items = h.items()
        items.sort()
        for key, val in items:
            print '  %s => %s' % (key, val)
        print "]"
    printSep()
The only reason I sort the keys here is to make sure that python and Perl print the elements of the dictionary in the same order. Note that sorting in Perl generates a new list, while in python sorting is done in-place. This means that you can avoid making a copy while sorting in python. The disadvantage is a clumsier syntax for the common case where you do want a copy. Larry Wall says that in Perl, you almost always do want the copy; I am not sure whether this is true in Python. If you wanted to do the copy, you would just do this (in Python 2.4+):
import sys

def printSep():
    print '=' * 60

def printLoH(s,loh):
    print s
    for h in loh:
        print "["
        for key, val in sorted(h.items()):
            print '  %s => %s' % (key, val)
        print "]"
    printSep()
Declaration of a list of hashes
@LoH = (
       {
          Lead      => "fred",
          Friend    => "barney",
       },
       {
           Lead     => "george",
           Wife     => "jane",
           Son      => "elroy",
       },
       {
           Lead     => "homer",
           Wife     => "marge",
           Son      => "bart",
       }
 );

printLoH ('initial value', \@LoH);
LoH = [
       {  "Lead"      : "fred",
          "Friend"    : "barney"
       },
       {
           "Lead"     : "george",
           "Wife"     : "jane",
           "Son"      : "elroy"
       },
       {
           "Lead"     : "homer",
           "Wife"     : "marge",
           "Son"      : "bart"
       }
      ]

printLoH ('initial value', LoH)
Generation of a list of hashes Reading a list of hashes from a file The format of the file is expected to be:
LEAD=fred FRIEND=barney
LEAD=homer WIFE=marge
...
my @LoH;
open my $f, "cooktest.4" or die $!;
while ( <$f> ) {
    my $rec = {};
    for my $field ( split ) {
        ($key, $value) = split /=/, $field;
        $rec->{$key} = $value;
    }
    push @LoH, $rec;
}

printLoH 'after reading from file cooktest.4', LoH;
LoH = []
for line in open("cooktest.4")
    rec = {}
    for field in line.split():
        key, value = field.split('=', 1)
        rec[key] = value
    LoH.append (rec)

printLoH ('after reading from file cooktest.4', LoH)
Reading a list of hashes from a file without temporaries
my @LoH;
open my $f, "cooktest.4" or die $!;
while ( <$f> ) {
    push @LoH, { split /[\s=]+/ };
}

printLoH ('direct read from file', \@LoH);
# This builds a list of (key, value) pairs, and then creates the
# dictionary from those.  A temporary pairs is used for readability
LoH = []
for line in open("cooktest.4")
    pairs = [field.split("=", 1) for field in line.split()]
    LoH.append(dict(pairs))

printLoH ('direct read from file', LoH)
If you really want no temporaries at all, you could (but shouldn't) use the one line list comprehension (line breaks for legibility):
LoH = [dict([field.split("=", 1)
             for field in line.split()])
                 for line in open("cooktest.4")]

printLoH ('direct read from file', LoH)
Generation of a list of hashes from function calls
Preliminaries
For convenience, these functions and variables are global. getnextpairset returns the elements of the array _getnextpairsetdata. I don't know why Tom chose to make this return a list in Perl, rather than a reference to a hash. Perhaps to keep the order. You can still initialize a hash with the result. In python, returning a dictionary is definitely the way to go.
$_getnextpairsetcounter = 0;
@_getnextpairsetdata =
  ( ["lead", "fred", "daughter", "pebbles"],
    ["lead", "kirk", "first_officer", "spock", "doc", "mccoy"]);

sub getnextpairset{
  if ($_getnextpairsetcounter > $#_getnextpairsetdata) { return (); }
  return @{$_getnextpairsetdata[$_getnextpairsetcounter++]};
}

sub parsepairs{
my $line = shift;
chomp $line;
return split (/[= ]/, $line);
}
_getnextpairsetcounter = 0
_getnextpairsetdata =\
  [ {"lead" : "fred", "daughter" : "pebbles"},
    {"lead" : "kirk", "first_officer" : "spock", "doc" : "mccoy"} ]

def getnextpairset():
  global _getnextpairsetcounter
  if _getnextpairsetcounter == len(_getnextpairsetdata) : return ''
  result = _getnextpairsetdata[_getnextpairsetcounter]
  _getnextpairsetcounter += 1
  return result

def parsepairs(line):
  line = line[:-1]   # chop last character off
  dict = {}
  pairs = regsub.split (line, "[= ]")
  for i in range(0, len(pairs), 2):
    dict[pairs[i]] = pairs[i+1]
  return dict
This would be much more elegant as a class, both in python and Perl. [add a pointer to classes when we get there]
Generation
Call a function returning a list (in Perl) or a dictionary (in python). In Perl, the list is of the form ("lead","fred","daughter","pebbles") ; in python, the dictionary is of the form {"lead" : "fred", "daughter" : "pebbles"} .
# calling a function  that returns a key,value list, like

my @LoH;
while ( my %fields = getnextpairset() ) {
   push @LoH, { %fields };
}
printLoH ('filled with getnextpairset', \@LoH);
LoH = []
while True:
  fields = getnextpairset()
  if not fields: break
  LoH.append (fields)

printLoH ('filled with getnextpairset', LoH)
Generation without temporaries
Sep 14, 2019 | wiki.python.org
my @LoH;
open my $f, "cooktest.4" or die $!;
while (<$f>) {
    push @LoH, { parsepairs($_) };
}

printLoH 'generated from function calls with no temps', \@LoH;
LoH = [parsepairs(line) for line in open("cooktest.4")]

printLoH ('generated from function calls with no temps', LoH)
Adding a key/value pair to an element
$LoH[0]{PET} = "dino";
$LoH[2]{PET} = "santa's little helper";

printLoH ('after addition of key/value pairs', \@LoH);
LoH[0]["PET"] = "dino"
LoH[2]["PET"] = "santa's little helper"

printLoH ('after addition of key/value pairs', LoH)
Accessing elements of a list of hashes
$LoH[0]{LEAD} = "fred";
print $LoH[0]{LEAD}, "\n";

s/(\w)/\u$1/, print "$_\n"
  for $LoH[1]{LEAD};

printSep();
LoH[0]["LEAD"] = "fred"
print (LoH[0]["LEAD"])

LoH[1]["LEAD"] = LoH[1]["LEAD"].title()
print (LoH[1]["LEAD"])

printSep()
Printing a list of hashes Simple print
for my $href ( @LoH ) {
    print "{ ";
    for my $role ( sort keys %$href ) {
        print "$role=$href->{$role} ";
    }
    print "}\n";
}
for href in LoH:
    print "{",
    items = href.items();
    items.sort()
    for role, val in items:
        print "%s=%s" %(role, val),
    print "}"

Note the comma after the print in the python segment -- this means "don't add a newline".

Print with indices
for my $i ( 0 .. $#LoH ) {
    print "$i is { ";
    for my $role ( sort keys %{ $LoH[$i] } ) {
        print "$role=$LoH[$i]{$role} ";
    }
    print "}\n";
}
for i, elem in enumerate(LoH):
    print i, "is {",
    items = elem.items();
    items.sort()
    for role, val in items:
        print "%s=%s" % (role, val),
    print "}"

Note the comma after the print in the python segment -- this means "don't add a newline". It does, however, add a space.

Print whole thing one at a time
for my $i ( 0 .. $#LoH ) {
    for my $role ( sort keys %{ $LoH[$i] } ) {
        print "elt $i $role is $LoH[$i]{$role}\n";
    }
}
for i, elem in enumerate(LoH):
    items = elem.items();
    items.sort()
    for role, val in items:
        print "elt", i, role, "is", val
Interface to the Tk GUI toolkit

The Perl versions of this code have not been tested, as we don't currently have a working version of Perl and Tk.

[Links to tkinter doc]

Perl/Tk Documentation

Preliminaries

All the following code snippets will need these declarations first:

use Tk;
from Tkinter import *
import sys
Hello world label
$top = MainWindow->new;
$hello = $top->Button(
    '-text'    => 'Hello, world',
    '-command' => sub {print STDOUT "Hello, world\n";exit 0;}
);
$hello->pack;
MainLoop;
top = Tk()
def buttonFunction () :
    print 'Hello, world'
    sys.exit (-1)

hello = Button(top, {'text' : 'Hello, world', 'command' : buttonFunction})
hello.pack()
top.mainloop()

clear


CategoryAdvocacy

PerlPhrasebook (last edited 2012-04-26 23:22:09 by 137 )

Unable to edit the page? See the FrontPage for instructions.

[Sep 12, 2019] Python for Perl Programmers by Tom Limoncelli

Sep 12, 2019 | everythingsysadmin.com

Tom Limoncelli's EverythingSysadmin Blog

Python for Perl Programmers There are certain Perl idioms that every Perl programmer uses: "while (<>) { foo; }" and "foo ~= s/old/new/g" both come to mind.

When I was learning Python I was pretty peeved that certain Python books don't get to that kind of thing until much later chapters. One didn't cover that kind of thing until the end! As [a long-time Perl user](https://everythingsysadmin.com/2011/03/overheard-at-the-office-perl-e.html) this annoyed and confused me.

While they might have been trying to send a message that Python has better ways to do those things, I think the real problem was that the audience for a general Python book is a lot bigger than the audience for a book for Perl people learning Python. Imagine how confusing it would be to a person learning their first programming language if their book started out comparing one language you didn't know to a different language you didn't know!

So here are the idioms I wish were in Chapter 1. I'll be updating this document as I think of new ones, but I'm trying to keep this to be a short list.

Processing every line in a file

Perl:

while (<>) {
    print $_;
}

Python:

for line in file('filename.txt'):
    print line

To emulate the Perl <> technique that reads every file on the command line or stdin if there is none:

import fileinput
for line in fileinput.input():
     print line

If you must access stdin directly, that is in the "sys" module:

import sys
for line in sys.stdin:
     print line

However, most Python programmers tend to just read the entire file into one huge string and process it that way. I feel funny doing that. Having used machines with very limited amounts of RAM, I tend to try to keep my file processing to a single line at a time. However, that method is going the way of the dodo.

contents = file('filename.txt').read()
all_input = sys.stdin.read()

If you want the file to be one string per line, with the newline removed just change read() to readlines()

list_of_strings = file('filename.txt').readlines()
all_input_as_list = sys.stdin.readlines()
Regular expressions

Python has a very powerful RE system, you just have to enable it with "import re". Any place you can use a regular expression you can also use a compiled regular expresion. Python people tend to always compile their regular expressions; I guess they aren't used to writing throw-away scripts like in Perl:

import re
RE_DATE = re.compile(r'\d\d\d\d-\d{1,2}-\d{1,2}')
for line in sys.stdin:
     mo = re.search(RE_DATE, line)
     if mo:
          print mo.group(0)

There is re.search() and re.match(). re.match() only matches if the string starts with the regular expression. It is like putting a "^" at the front of your regex. re.search() is like putting a ".*" at the front of your regex. Since match comes before search alphabetically, most Perl users find "match" in the documentation, try to use it, and get confused that r'foo' does not match 'i foo you'. My advice? Pretend match doesn't exist (just kidding).

The big change you'll have to get used to is that the result of a match is an object, and you pull various bits of information from the object. If nothing is found, you don't get an object, you get None, which makes it easy to test for in a if/then. An object is always True, None is always false. Now that code above makes more sense, right?

Yes, you can put parenthesis around parts of the regular expression to extract out data. That's where the match object that gets returned is pretty cool:

import re
for line in sys.stdin:
     mo = re.search(r'(\d\d\d\d)-(\d{1,2})-(\d{1,2})', line)
     if mo:
          print mo.group(0)

The first thing you'll notice is that the "mo =" and the "if" are on separate lines. There is no "if x = re.search() then" idiom in Python like there is in Perl. It is annoying at first, but eventually I got used to it and now I appreciate that I can't accidentally assign a variable that I meant to compare.

Let's look at that match object that we assigned to the variable "mo" earlier:

The perl s// substitutions are easily done with re.sub() but if you don't require a regular expression "replace" is much faster:

>>> re.sub(r'\d\d+', r'', '1 22 333 4444 55555')
'1    '

>>> re.sub(r'\d+', r'', '9876 and 1234')
' and '

>>> re.sub(r'remove', r'', 'can you remove from')
'can you  from'

>>> 'can you remove from'.replace('remove', '')
'can you  from'

You can even do multiple parenthesis substitutions as you would expect:

>>> re.sub(r'(\d+) and (\d+)', r'yours=\1 mine=\2', '9876 and 1234')
'yours=9876 mine=1234'

After you get used to that, read the ""pydoc re" page":http://docs.python.org/library/re.html for more information.

String manipulations

I found it odd that Python folks don't use regular expressions as much as Perl people. At first I though this was due to the fact that Python makes it more cumbersome ('cause I didn't like to have to do 'import re'). It turns out that Python string handling can be more powerful. For example the common Perl idiom "s/foo/bar" (as long as "foo" is not a regex) is as simple as:

credit = 'i made this'
print credit.replace('made', 'created')

or

print 'i made this'.replace('made', 'created')

It is kind of fun that strings are objects that have methods. It looks funny at first.

Notice that replace returns a string. It doesn't modify the string. In fact, strings can not be modified, only created. Python cleans up for automatically, and it can't do that very easily if things change out from under it. This is very Lisp-like. This is odd at first but you get used to it. Wait... by "odd" I mean "totally fucking annoying". However, I assure you that eventually you'll see the benefits of string de-duplication and (I'm told) speed.

It does mean, however, that accumulating data in a string is painfully slow:

s = 'this is the first part\n'
s += 'i added this.\n'
s += 'and this.\n'
s += 'and then this.\n'

The above code is bad. Each assignment copies all the previous data just to make a new string. The more you accumulate, the more copying is needed. The Pythonic way is to accumulate a list of the strings and join them later.

s = []
s.append('this is the first part\n')
s.append('i added this.\n')
s.append('and this.\n')
s.append('and then this.\n')
print ''.join(s)

It seems slower, but it is actually faster. The strings stay in their place. Each addition to "s" is just adding a pointer to where the strings are in memory. You've essentially built up a linked list of pointers, which are much more light-weight and faster to manage than copying those strings around. At the end, you join the strings. Python makes one run through all the strings, copying them to a buffer, a pointer to which is sent to the "print" routine. This is about the same amount of work as Perl, which internally was copying the strings into a buffer along the way. Perl did copy-bytes, copy-bytes, copy-bytes, copy-bytes, pass pointer to print. Python did append-pointer 4 times then a highly optimized copy-bytes, copy-bytes, copy-bytes, copy-bytes, pass pointer to print.

joining and splitting.

This killed me until I got used to it. The join string is not a parameter to join but is a method of the string type.

Perl:

new = join('|', str1, str2, str3)

Python:

new = '|'.join([str1, str2, str3])

Python's join is a function of the delimiter string. It hurt my brain until I got used to it.

Oh, the join() function only takes one argument. What? It's joining a list of things... why does it take only one argument? Well, that one argument is a list. (see example above). I guess that makes the syntax more uniform.

Splitting strings is much more like Perl... kind of. The parameter is what you split on, or leave it blank for "awk-like splitting" (which heathens call "perl-like splitting" but they are forgetting their history).

Perl:

my @values = split('|', $data);

Python:

values = data.split('|');

You can split a string literal too.  In this example we don't give split() any parameters so that it does "awk-like splitting".
print 'one two three four'.split()
['one', 'two', 'three', 'four']

If you have a multi-line string that you want to break into its individual lines, bigstring.splitlines() will do that for you.

Getting help
pydoc foo

except it doesn't work half the time because you need to know the module something is in . I prefer the "quick search" box on http://docs.python.org or "just use Google".

I have not read ""Python for Unix and Linux System Administration":http://www.amazon.com/dp/0596515820/safocus-20" but the table of contents looks excellent. I have read most of Python Cookbook (the first edition, there is a 2nd edition out too) and learned a lot. Both are from O'R eilly and can be read on Safari Books Online .

That's it!

That's it! Those few idioms make up most of the Perl code I usually wrote. Learning Python would have been so much easier if someone had showed me the Python equivalents early on.

One last thing... As a sysadmin there are a few modules that I've found useful:

14 Comments swheatley | March 31, 2011 9:26 AM Once you get comfortable with Python basics, I highly recommend checking out David Beazley's "Generator Tricks for System Programmers" . This is a great compromise between the classic one-line-at-a-time processing you mention in your post, but allows you to treat the source as if all the lines were read into memory already. John | March 31, 2011 4:17 PM Would be nice if you also included an example of doing regex-based search/replace when there's ()'s involved.
Paddy3118 | April 1, 2011 3:00 AM You missed the following page that does more of the same for Python 2.X:

http://wiki.python.org/moin/PerlPhrasebook

- Paddy.
Chaos | April 2, 2011 10:14 PM Do you know of any good references for pexpect? I use it a lot, but i wouldn't say i've gotten used to it (i'm not really an expect expert either), and i get bitten a lot. askarali | April 4, 2011 1:58 PM Do you recommend any book of Python for system admins? or any suggestion to start learning Python for system administration. martin | April 5, 2011 4:48 PM I am pretty sure that "odd" behavior in python is also there in perl. I recall helping debu a problem for some bioinformatics software in perl about 10 years back and they were appending little pieces to a perl string about a million times and wondered why the script took forever. Of has perl changed since then? Tom Limoncelli replied to comment from martin | April 6, 2011 10:36 AM Perl will only recopy the string if it needs to because the buffer allocated to it has run out of space. It will allocate a new (larger) buffer, copy the string there, and do the operation in that new buffer. If you keep appending small strings to a string, it may have to recopy the string every time, or every other time, or less depending on how much extra space it allocates. However, you can modify the string in-place without causing it to need to recopy if the change doesn't affect the length of the string. In other words, you can "poke" a replacement character at position 3 to change '123456' to '123x56'.

Python, however, can not change a string. Ever. They are allocated with the exact amount of space required, no extra, and even then they are immutable. You can't take a string and change the 3rd char in. Methods like replace() return a new string with the result; the old string is still there. Something like "x += 'foo'" creates a new string and destroys the old one invisibly.
Gustavo Chaves | April 17, 2011 7:19 PM Perl regexes are implicitly compiled unless they are the result of scalar interpolation. That's why you only ocasionally see things like qr/RE/ or /RE/o in scripts. In Python you have to be explicit all the time I guess.
Jack | April 4, 2012 11:37 AM argparse >> gflags uwe | April 4, 2012 2:06 PM On the split part, in python it would be:
values = data.split('|') Tom Limoncelli replied to comment from uwe | April 4, 2012 3:53 PM Good point. I've updated the doc. Thanks! Sunil Kartikey | November 20, 2013 12:04 PM Thanks Alex Aminoff | December 6, 2013 4:45 PM I'm really having a hard time understanding how to easily and quickly interpolate variables into strings, especially for repetitive stuff like debug messages.

In perl, I surely spend half my day typing

print "at this point in the program, here is foo:$foo bar:$bar" if $debug

In python, there are several ways to do this but it appears that they either require more typing, especially closing the quote on my string and using +, or referring to each substituted string in two places, like

print " foo:%s bar:%s" % str(foo),str(bar)

which is terrible because if I want to add another variable baz, I have to modify two places in the line.

I need this to be really easy because my generate and test cycle frequently includes such print statements.

Do python programmers just do the entire generate and test cycle in some different way? Bob DuCharme | January 20, 2015 5:22 PM Thanks for writing this. You wrote "Imagine how confusing it would be to a person learning their first programming language if their book started out comparing one language you didn't know to a different language you didn't know!" I've been learning about Scala lately, and I know the basics of Java, but most tutorials assume that you know Java really well, which is annoying. Best of Blog

I'm going to LISA16 Navigation Recent Entries Search

Search blog entries:

Archives RSS Feed Syndicate this site (XML) Credits

[Mar 17, 2019] Translating Perl to Python

Mar 17, 2019 | stackoverflow.com

21


John Kugelman ,Jul 1, 2009 at 3:29

I found this Perl script while migrating my SQLite database to mysql

I was wondering (since I don't know Perl) how could one rewrite this in Python?

Bonus points for the shortest (code) answer :)

edit : sorry I meant shortest code, not strictly shortest answer

#! /usr/bin/perl

while ($line = <>){
    if (($line !~  /BEGIN TRANSACTION/) && ($line !~ /COMMIT/) && ($line !~ /sqlite_sequence/) && ($line !~ /CREATE UNIQUE INDEX/)){

        if ($line =~ /CREATE TABLE \"([a-z_]*)\"(.*)/){
                $name = $1;
                $sub = $2;
                $sub =~ s/\"//g; #"
                $line = "DROP TABLE IF EXISTS $name;\nCREATE TABLE IF NOT EXISTS $name$sub\n";
        }
        elsif ($line =~ /INSERT INTO \"([a-z_]*)\"(.*)/){
                $line = "INSERT INTO $1$2\n";
                $line =~ s/\"/\\\"/g; #"
                $line =~ s/\"/\'/g; #"
        }else{
                $line =~ s/\'\'/\\\'/g; #'
        }
        $line =~ s/([^\\'])\'t\'(.)/$1THIS_IS_TRUE$2/g; #'
        $line =~ s/THIS_IS_TRUE/1/g;
        $line =~ s/([^\\'])\'f\'(.)/$1THIS_IS_FALSE$2/g; #'
        $line =~ s/THIS_IS_FALSE/0/g;
        $line =~ s/AUTOINCREMENT/AUTO_INCREMENT/g;
        print $line;
    }
}

Some additional code was necessary to successfully migrate the sqlite database (handles one line Create table statements, foreign keys, fixes a bug in the original program that converted empty fields '' to \' .

I posted the code on the migrating my SQLite database to mysql Question

Jiaaro ,Jul 2, 2009 at 10:15

Here's a pretty literal translation with just the minimum of obvious style changes (putting all code into a function, using string rather than re operations where possible).
import re, fileinput

def main():
  for line in fileinput.input():
    process = False
    for nope in ('BEGIN TRANSACTION','COMMIT',
                 'sqlite_sequence','CREATE UNIQUE INDEX'):
      if nope in line: break
    else:
      process = True
    if not process: continue
    m = re.search('CREATE TABLE "([a-z_]*)"(.*)', line)
    if m:
      name, sub = m.groups()
      line = '''DROP TABLE IF EXISTS %(name)s;
CREATE TABLE IF NOT EXISTS %(name)s%(sub)s
'''
      line = line % dict(name=name, sub=sub)
    else:
      m = re.search('INSERT INTO "([a-z_]*)"(.*)', line)
      if m:
        line = 'INSERT INTO %s%s\n' % m.groups()
        line = line.replace('"', r'\"')
        line = line.replace('"', "'")
    line = re.sub(r"([^'])'t'(.)", r"\1THIS_IS_TRUE\2", line)
    line = line.replace('THIS_IS_TRUE', '1')
    line = re.sub(r"([^'])'f'(.)", r"\1THIS_IS_FALSE\2", line)
    line = line.replace('THIS_IS_FALSE', '0')
    line = line.replace('AUTOINCREMENT', 'AUTO_INCREMENT')
    print line,

main()

dr jimbob ,May 20, 2018 at 0:54

Alex Martelli's solution above works good, but needs some fixes and additions:

In the lines using regular expression substitution, the insertion of the matched groups must be double-escaped OR the replacement string must be prefixed with r to mark is as regular expression:

line = re.sub(r"([^'])'t'(.)", "\\1THIS_IS_TRUE\\2", line)

or

line = re.sub(r"([^'])'f'(.)", r"\1THIS_IS_FALSE\2", line)

Also, this line should be added before print:

line = line.replace('AUTOINCREMENT', 'AUTO_INCREMENT')

Last, the column names in create statements should be backticks in MySQL. Add this in line 15:

  sub = sub.replace('"','`')

Here's the complete script with modifications:

import re, fileinput

def main():
  for line in fileinput.input():
    process = False
    for nope in ('BEGIN TRANSACTION','COMMIT',
                 'sqlite_sequence','CREATE UNIQUE INDEX'):
      if nope in line: break
    else:
      process = True
    if not process: continue
    m = re.search('CREATE TABLE "([a-z_]*)"(.*)', line)
    if m:
      name, sub = m.groups()
      sub = sub.replace('"','`')
      line = '''DROP TABLE IF EXISTS %(name)s;
CREATE TABLE IF NOT EXISTS %(name)s%(sub)s
'''
      line = line % dict(name=name, sub=sub)
    else:
      m = re.search('INSERT INTO "([a-z_]*)"(.*)', line)
      if m:
        line = 'INSERT INTO %s%s\n' % m.groups()
        line = line.replace('"', r'\"')
        line = line.replace('"', "'")
    line = re.sub(r"([^'])'t'(.)", "\\1THIS_IS_TRUE\\2", line)
    line = line.replace('THIS_IS_TRUE', '1')
    line = re.sub(r"([^'])'f'(.)", "\\1THIS_IS_FALSE\\2", line)
    line = line.replace('THIS_IS_FALSE', '0')
    line = line.replace('AUTOINCREMENT', 'AUTO_INCREMENT')
    if re.search('^CREATE INDEX', line):
        line = line.replace('"','`')
    print line,

main()

Brad Gilbert ,Jul 1, 2009 at 18:43

Here is a slightly better version of the original.
#! /usr/bin/perl
use strict;
use warnings;
use 5.010; # for s/\K//;

while( <> ){
  next if m'
    BEGIN TRANSACTION   |
    COMMIT              |
    sqlite_sequence     |
    CREATE UNIQUE INDEX
  'x;

  if( my($name,$sub) = m'CREATE TABLE \"([a-z_]*)\"(.*)' ){
    # remove "
    $sub =~ s/\"//g; #"
    $_ = "DROP TABLE IF EXISTS $name;\nCREATE TABLE IF NOT EXISTS $name$sub\n";

  }elsif( /INSERT INTO \"([a-z_]*)\"(.*)/ ){
    $_ = "INSERT INTO $1$2\n";

    # " => \"
    s/\"/\\\"/g; #"
    # " => '
    s/\"/\'/g; #"

  }else{
    # '' => \'
    s/\'\'/\\\'/g; #'
  }

  # 't' => 1
  s/[^\\']\K\'t\'/1/g; #'

  # 'f' => 0
  s/[^\\']\K\'f\'/0/g; #'

  s/AUTOINCREMENT/AUTO_INCREMENT/g;
  print;
}

Mickey Mouse ,Jun 14, 2011 at 15:48

all of scripts on this page can't deal with simple sqlite3:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE Filename (
  FilenameId INTEGER,
  Name TEXT DEFAULT '',
  PRIMARY KEY(FilenameId) 
  );
INSERT INTO "Filename" VALUES(1,'');
INSERT INTO "Filename" VALUES(2,'bigfile1');
INSERT INTO "Filename" VALUES(3,'%gconf-tree.xml');

None were able to reformat "table_name" into proper mysql's `table_name` . Some messed up empty string value.

Sinan Ünür ,Jul 1, 2009 at 3:24

I am not sure what is so hard to understand about this that it requires a snide remark as in your comment above. Note that <> is called the diamond operator. s/// is the substitution operator and // is the match operator m// .

Ken_g6 ,Jul 1, 2009 at 3:22

Based on http://docs.python.org/dev/howto/regex.html ...
  1. Replace $line =~ /.*/ with re.search(r".*", line) .
  2. $line !~ /.*/ is just !($line =~ /.*/) .
  3. Replace $line =~ s/.*/x/g with line=re.sub(r".*", "x", line) .
  4. Replace $1 through $9 inside re.sub with \1 through \9 respectively.
  5. Outside a sub, save the return value, i.e. m=re.search() , and replace $1 with the return value of m.group(1) .
  6. For "INSERT INTO $1$2\n" specifically, you can do "INSERT INTO %s%s\n" % (m.group(1), m.group(2)) .

hpavc ,Jul 1, 2009 at 12:33

Real issue is do you know actually how to migrate the database? What is presented is merely a search and replace loop.

> ,

Shortest? The tilde signifies a regex in perl. "import re" and go from there. The only key differences are that you'll be using \1 and \2 instead of $1 and $2 when you assign values, and you'll be using %s for when you're replacing regexp matches inside strings.

[Mar 16, 2019] Translating Perl to Python - Stack Overflow

Mar 16, 2019 | stackoverflow.com

Translating Perl to Python Ask Question 21


John Kugelman ,Jul 1, 2009 at 3:29

I found this Perl script while migrating my SQLite database to mysql

I was wondering (since I don't know Perl) how could one rewrite this in Python?

Bonus points for the shortest (code) answer :)

edit : sorry I meant shortest code, not strictly shortest answer

#! /usr/bin/perl

while ($line = <>){
    if (($line !~  /BEGIN TRANSACTION/) && ($line !~ /COMMIT/) && ($line !~ /sqlite_sequence/) && ($line !~ /CREATE UNIQUE INDEX/)){

        if ($line =~ /CREATE TABLE \"([a-z_]*)\"(.*)/){
                $name = $1;
                $sub = $2;
                $sub =~ s/\"//g; #"
                $line = "DROP TABLE IF EXISTS $name;\nCREATE TABLE IF NOT EXISTS $name$sub\n";
        }
        elsif ($line =~ /INSERT INTO \"([a-z_]*)\"(.*)/){
                $line = "INSERT INTO $1$2\n";
                $line =~ s/\"/\\\"/g; #"
                $line =~ s/\"/\'/g; #"
        }else{
                $line =~ s/\'\'/\\\'/g; #'
        }
        $line =~ s/([^\\'])\'t\'(.)/$1THIS_IS_TRUE$2/g; #'
        $line =~ s/THIS_IS_TRUE/1/g;
        $line =~ s/([^\\'])\'f\'(.)/$1THIS_IS_FALSE$2/g; #'
        $line =~ s/THIS_IS_FALSE/0/g;
        $line =~ s/AUTOINCREMENT/AUTO_INCREMENT/g;
        print $line;
    }
}

Some additional code was necessary to successfully migrate the sqlite database (handles one line Create table statements, foreign keys, fixes a bug in the original program that converted empty fields '' to \' .

I posted the code on the migrating my SQLite database to mysql Question

Jiaaro ,Jul 2, 2009 at 10:15

Here's a pretty literal translation with just the minimum of obvious style changes (putting all code into a function, using string rather than re operations where possible).
import re, fileinput

def main():
  for line in fileinput.input():
    process = False
    for nope in ('BEGIN TRANSACTION','COMMIT',
                 'sqlite_sequence','CREATE UNIQUE INDEX'):
      if nope in line: break
    else:
      process = True
    if not process: continue
    m = re.search('CREATE TABLE "([a-z_]*)"(.*)', line)
    if m:
      name, sub = m.groups()
      line = '''DROP TABLE IF EXISTS %(name)s;
CREATE TABLE IF NOT EXISTS %(name)s%(sub)s
'''
      line = line % dict(name=name, sub=sub)
    else:
      m = re.search('INSERT INTO "([a-z_]*)"(.*)', line)
      if m:
        line = 'INSERT INTO %s%s\n' % m.groups()
        line = line.replace('"', r'\"')
        line = line.replace('"', "'")
    line = re.sub(r"([^'])'t'(.)", r"\1THIS_IS_TRUE\2", line)
    line = line.replace('THIS_IS_TRUE', '1')
    line = re.sub(r"([^'])'f'(.)", r"\1THIS_IS_FALSE\2", line)
    line = line.replace('THIS_IS_FALSE', '0')
    line = line.replace('AUTOINCREMENT', 'AUTO_INCREMENT')
    print line,

main()

dr jimbob ,May 20, 2018 at 0:54

Alex Martelli's solution above works good, but needs some fixes and additions:

In the lines using regular expression substitution, the insertion of the matched groups must be double-escaped OR the replacement string must be prefixed with r to mark is as regular expression:

line = re.sub(r"([^'])'t'(.)", "\\1THIS_IS_TRUE\\2", line)

or

line = re.sub(r"([^'])'f'(.)", r"\1THIS_IS_FALSE\2", line)

Also, this line should be added before print:

line = line.replace('AUTOINCREMENT', 'AUTO_INCREMENT')

Last, the column names in create statements should be backticks in MySQL. Add this in line 15:

  sub = sub.replace('"','`')

Here's the complete script with modifications:

import re, fileinput

def main():
  for line in fileinput.input():
    process = False
    for nope in ('BEGIN TRANSACTION','COMMIT',
                 'sqlite_sequence','CREATE UNIQUE INDEX'):
      if nope in line: break
    else:
      process = True
    if not process: continue
    m = re.search('CREATE TABLE "([a-z_]*)"(.*)', line)
    if m:
      name, sub = m.groups()
      sub = sub.replace('"','`')
      line = '''DROP TABLE IF EXISTS %(name)s;
CREATE TABLE IF NOT EXISTS %(name)s%(sub)s
'''
      line = line % dict(name=name, sub=sub)
    else:
      m = re.search('INSERT INTO "([a-z_]*)"(.*)', line)
      if m:
        line = 'INSERT INTO %s%s\n' % m.groups()
        line = line.replace('"', r'\"')
        line = line.replace('"', "'")
    line = re.sub(r"([^'])'t'(.)", "\\1THIS_IS_TRUE\\2", line)
    line = line.replace('THIS_IS_TRUE', '1')
    line = re.sub(r"([^'])'f'(.)", "\\1THIS_IS_FALSE\\2", line)
    line = line.replace('THIS_IS_FALSE', '0')
    line = line.replace('AUTOINCREMENT', 'AUTO_INCREMENT')
    if re.search('^CREATE INDEX', line):
        line = line.replace('"','`')
    print line,

main()

Brad Gilbert ,Jul 1, 2009 at 18:43

Here is a slightly better version of the original.
#! /usr/bin/perl
use strict;
use warnings;
use 5.010; # for s/\K//;

while( <> ){
  next if m'
    BEGIN TRANSACTION   |
    COMMIT              |
    sqlite_sequence     |
    CREATE UNIQUE INDEX
  'x;

  if( my($name,$sub) = m'CREATE TABLE \"([a-z_]*)\"(.*)' ){
    # remove "
    $sub =~ s/\"//g; #"
    $_ = "DROP TABLE IF EXISTS $name;\nCREATE TABLE IF NOT EXISTS $name$sub\n";

  }elsif( /INSERT INTO \"([a-z_]*)\"(.*)/ ){
    $_ = "INSERT INTO $1$2\n";

    # " => \"
    s/\"/\\\"/g; #"
    # " => '
    s/\"/\'/g; #"

  }else{
    # '' => \'
    s/\'\'/\\\'/g; #'
  }

  # 't' => 1
  s/[^\\']\K\'t\'/1/g; #'

  # 'f' => 0
  s/[^\\']\K\'f\'/0/g; #'

  s/AUTOINCREMENT/AUTO_INCREMENT/g;
  print;
}

Mickey Mouse ,Jun 14, 2011 at 15:48

all of scripts on this page can't deal with simple sqlite3:
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE Filename (
  FilenameId INTEGER,
  Name TEXT DEFAULT '',
  PRIMARY KEY(FilenameId) 
  );
INSERT INTO "Filename" VALUES(1,'');
INSERT INTO "Filename" VALUES(2,'bigfile1');
INSERT INTO "Filename" VALUES(3,'%gconf-tree.xml');

None were able to reformat "table_name" into proper mysql's `table_name` . Some messed up empty string value.

Sinan Ünür ,Jul 1, 2009 at 3:24

I am not sure what is so hard to understand about this that it requires a snide remark as in your comment above. Note that <> is called the diamond operator. s/// is the substitution operator and // is the match operator m// .

Ken_g6 ,Jul 1, 2009 at 3:22

Based on http://docs.python.org/dev/howto/regex.html ...
  1. Replace $line =~ /.*/ with re.search(r".*", line) .
  2. $line !~ /.*/ is just !($line =~ /.*/) .
  3. Replace $line =~ s/.*/x/g with line=re.sub(r".*", "x", line) .
  4. Replace $1 through $9 inside re.sub with \1 through \9 respectively.
  5. Outside a sub, save the return value, i.e. m=re.search() , and replace $1 with the return value of m.group(1) .
  6. For "INSERT INTO $1$2\n" specifically, you can do "INSERT INTO %s%s\n" % (m.group(1), m.group(2)) .

hpavc ,Jul 1, 2009 at 12:33

Real issue is do you know actually how to migrate the database? What is presented is merely a search and replace loop.

> ,

Shortest? The tilde signifies a regex in perl. "import re" and go from there. The only key differences are that you'll be using \1 and \2 instead of $1 and $2 when you assign values, and you'll be using %s for when you're replacing regexp matches inside strings.

[Mar 16, 2019] Regex translation from Perl to Python - Stack Overflow

Mar 16, 2019 | stackoverflow.com

Regex translation from Perl to Python Ask Question 1


royskatt ,Jan 30, 2014 at 14:45

I would like to rewrite a small Perl programm to Python. I am processing text files with it as follows:

Input:

00000001;Root;;
00000002;  Documents;;
00000003;    oracle-advanced_plsql.zip;file;
00000004;  Public;;
00000005;  backup;;
00000006;    20110323-JM-F.7z.001;file;
00000007;    20110426-JM-F.7z.001;file;
00000008;    20110603-JM-F.7z.001;file;
00000009;    20110701-JM-F-via-summer_school;;
00000010;      20110701-JM-F-yyy.7z.001;file;

Desired output:

00000001;;Root;;
00000002;  ;Documents;;
00000003;    ;oracle-advanced_plsql.zip;file;
00000004;  ;Public;;
00000005;  ;backup;;
00000006;    ;20110323-JM-F.7z.001;file;
00000007;    ;20110426-JM-F.7z.001;file;
00000008;    ;20110603-JM-F.7z.001;file;
00000009;    ;20110701-JM-F-via-summer_school;;
00000010;      ;20110701-JM-F-yyy.7z.001;file;

Here is the working Perl code:

#filename: perl_regex.pl
#/usr/bin/perl -w
while(<>) {                                                           
  s/^(.*?;.*?)(\w)/$1;$2/;                                            
  print $_;                                                           
}

It call it from the command line: perl_regex.pl input.txt

Explanation of the Perl-style regex:

s/        # start search-and-replace regexp
  ^       # start at the beginning of this line
  (       # save the matched characters until ')' in $1
    .*?;  # go forward until finding the first semicolon
    .*?   # go forward until finding... (to be continued below)
  )
  (       # save the matched characters until ')' in $2
    \w    # ... the next alphanumeric character.
  )
/         # continue with the replace part
  $1;$2   # write all characters found above, but insert a ; before $2
/         # finish the search-and-replace regexp.

Could anyone tell me, how to get the same result in Python? Especially for the $1 and $2 variables I couldn't find something alike.

royskatt ,Jan 31, 2014 at 6:18

Python regular expression is very similar to Perl's, except:

Use re.sub to replace.

import re
import sys

for line in sys.stdin: # Explicitly iterate standard input line by line
    # `line` contains trailing newline!
    line = re.sub(r'^(.*?;.*?)(\w)', r'\1;\2', line)
    #print(line) # This print trailing newline
    sys.stdout.write(line) # Print the replaced string back.

royskatt ,Jan 31, 2014 at 16:36

The replace instruction for s/pattern/replace/ in python regexes is the re.sub(pattern, replace, string) function, or re.compile(pattern).sub(replace, string). In your case, you will do it so:
_re_pattern = re.compile(r"^(.*?;.*?)(\w)")
result = _re_pattern.sub(r"\1;\2", line)

Note that $1 becomes \1 . As for perl, you need to iterate over your lines the way you want to do it (open, inputfile, splitlines, ...).

[Dec 03, 2017] Perl index function equivalent in Python

Notable quotes:
"... string.find(s, sub[, start[, end]]) Return the lowest index in s where the substring sub is found such that sub is wholly contained in s[start:end]. Return -1 on failure. Defaults for start and end and interpretation of negative values is the same as for slices. ..."
Dec 03, 2017 | stackoverflow.com

Syed Mustafa Zinoor ,Mar 4, 2015 at 15:51

The index() in Perl returns the location of a text between a start point and an endpoint. Is there something similar in Python. If not how can this be implemented.

Example : in Perl, I would write an index function to return the index of a string as follows

start = index(input_text,text_to_search,starting_point_of_search)+off_set_length

What should be the equivalent in Python?

Kasramvd ,Mar 4, 2015 at 15:54

In python you can use str.find() to find the index of a sub-string inside a string :
>>> s
'123string 1abcabcstring 2123string 3abc123stringnabc'

>>> s.find('3a')
35

string.find(s, sub[, start[, end]]) Return the lowest index in s where the substring sub is found such that sub is wholly contained in s[start:end]. Return -1 on failure. Defaults for start and end and interpretation of negative values is the same as for slices.

[Nov 10, 2017] Python -- Perl function equivalence by Martin C. Brown

Nov 02, 2001 | perlmonks.com
abs(x) Perl equivalent: abs(x)

Returns the absolute value of a number (plain or long integer or floating point number). If you supply a complex number then only the magnitude is returned.

For example:

>>> print abs( -- 2.4)
2.4
>>> print abs(4+2j)
4.472135955
apply(function, args [, keywords ]) Perl equivalent: none

Applies the arguments args to function, which must be a function, method or other callable object. The args must be supplied as a sequence, lists are converted to tuples before being applied. The function is called using args as individual arguments, for example:

apply(add,(1,3,4))

is equivalent to:

add(1,3,4)

You need to use the apply function in situations where you are building up a list of arguments in a list or tuple and want to supply the list as individual arguments. This is especially useful in situations where you want to supply a varying list of arguments to a function.

The optional keywords argument should be a dictionary whose keys are strings, these will be used as keyword arguments to be supplied to the end of the argument list.

Notes for Perl programmers

The apply() function gets round the absence in Python of a way of dynamically calling a method or function. It also solves problems where you need to supply a list of arguments to a function that you are building dynamically. In Perl, arguments are progressively taken off an argument stack ( @_ ), whereas Python uses fixed argument names. The apply() is frequently used where we need to supply a variable list of arguments to the function that we've probably built up in an array or tuple.

You can also use it to call a function or method based on a string by using the return value from a call to eval(). The eval() function returns a valid Python expression, which can include a valid method or code object. For example, here's a function called run() which runs the method cmd on the imapcon object, which is actually an instance of the imaplib class for communicating with IMAP servers:

def run(cmd, args):
    typ, dat = apply(eval('imapcon.%s' % cmd), args)
    return dat

The imaplib module provides methods for all of the standard IMAP commands. So, to obtain the number of messages you send the select function, which means calling the select() method on an imaplib instance. By using the function above we can execute the select() method using:

run('select',())

This in effect calls:

imapcon.select()

We can get the contents of a specific message using:

data = run('fetch', (message,'(FLAGS
RFC822.HEADER)'))[0]

In Perl, we'd do the same thing by using a symbolic reference, or by using the symbol table to determine the code reference we need to use. For example, a typical trick is to dynamically call a function based on a string supplied by the user, often within a web application:

my $func = sprintf("%s_%s",$action,$subaction);
*code = \&{$func};
&code($user,$group,$session);
buffer(object [, offset [, size ] ]) Perl equivalent: none

Creates a new buffer on the object providing it supports the buffer call interface (such objects include strings, arrays, and buffers). The new buffer references the object using a slice starting from offset and extending to the end of the object or to the length size. If no arguments are given then the buffer covers the entire sequence.

Buffer objects are used to create a more friendly interface to certain object types. For example, the string object type is made available through a buffer object which allows you to access the information within the string on a byte by byte basis.

Notes for Perl programmers

The buffer() is similar in principle to the tie system for tying complex data structures to a simplified structure. However, whereas the tie system is flexible enough to provide you with different methods for accessing scalar, array or hash data sources, the buffer() function is only suitable for sequence objects.

callable(object) Perl equivalent: UNIVERSAL::can(METHOD) or exists() when supplied a function reference

Returns true if object is callable, false if not. Callable objects include functions, methods and code objects, and also classes (which return a new instance when called) and class instances which have the call method defined.

Notes for Perl programmers

The callable() function is slightly different to the closest suggestion given above. The callable() function only returns true if the method is defined within the given instance or class, it doesn't return a reference to the method itself. Also, callable() is designed to test any object or class that could be callable. This makes it appear to be as flexible as both UNIVERSAL::can() and defined(), when in truth all Python entities are objects or classes.

chr(i) Perl equivalent: chr()

Returns a single character string matching the ASCII code i. For example:

>>> print chr(72)+chr(101)+chr(108)+chr(108)+chr(111)
Hello

The chr() function is the opposite of ord() which converts characters back to ASCII integer codes. The argument should be in the range 0 to 255, a ValueError exception will be raised if the argument is outside that limit.

cmp(x, y) Perl equivalent: The <=> and cmp operators

Compares the two objects and and returns an integer according to the outcome. The return value is negative if x < y, zero if x == y and positive if x > y. Note that this specifically compares the values rather than any reference relationship, such that:

>>> a = 99
>>> b = int('99')
>>> cmp(a,b)
0
Notes for Perl programmers

The cmp() function in Python is similar to the cmp operator in Perl, in that it compares the values of the objects you supply as arguments, but unlike Perl's cmp it works on all objects. You should be using cmp() within a sort() method to guarantee the correct sorting order.

coerce(x, y)

Perl equivalent: none

Return a tuple consisting of the two numeric arguments converted to a common type, using the same rules as used by arithmetic operations. For example:

>>> a = 1
>>> b = 1.2
>>> coerce(a,b)
(1.0, 1.2)
>>> a = 1+2j
>>> b = 4.3e10
>>> coerce(a,b)
((1+2j), (43000000000+0j))
Notes for Perl programmers

Perl automatically translates between strings, integers and floating point numbers during any numerical expression. Although Python does not perform the automatic conversion of strings to numerical values (see the float() and int() functions later in this chapter), numbers are converted between integer, floating point, and complex types. The coerce() function exists to avoid constructs like:

$fpvalue = $intvalue/1.0;
compile(string, filename, kind)  Perl equivalent: anonymous subroutine

Compile string into a code object, which can later be executed by the exec statement to evaluate using eval(). The filename should be the name of the file from which the code was read, or a suitable identifier if generated internally. The kind argument specifies what kind of code is contained in string. See Table 8.1 for more information of the possible values.

Table 8.1. The kinds of code compiled by compile()
Kind value Code compiled
exec Sequence of statements
eval Single expression
single Single interactive statement

For example:

>>> a = compile('print "Hello World"','<string>','single')
>>> exec(a)
Hello World
>>> eval(a)
Hello World
Notes for Perl programmers

This is similar, but not identical to the process for creating anonymous functions within Perl, which internally create CV (Code Value) objects. However, compile() more closely matches the result of a parsed but unexecuted Perl eval() function call. Instead of returning a value, compile() returns the pre-compiled code ready to be executed.

complex(real [, imag ]) Perl equivalent: none

Returns a complex number with the real component real and the imaginary component imag, if supplied.

delattr(object, name) Perl equivalent: the delete() function on hash/array based objects

Deletes the attribute name from the object object, providing the object allows you to. Identical to the statement:

del object.name

However, it allows you to define object and name pragmatically, rather than explicitly in the code.

dir( [object ]) Perl equivalent: none

When supplied without an argument lists the names within the current local symbol table. For example:

>>> import smtplib, sys, os
>>> dir()
['__builtins__', '__doc__', '__name__', 'os', 'smtplib',
'sys']

When supplied with an argument, returns a list of attributes for that object. This can be useful for determining the objects and methods defined within a module:

>>> import sys
>>> dir(sys)
['__doc__', '__name__', '__stderr__', '__stdin__',
'__stdout__',
'argv', 'builtin_module_names', 'byteorder',
'copyright',
'exc_info', 'exc_type', 'exec_prefix', 'executable',
'exit',
'getdefaultencoding', 'getrecursionlimit',
'getrefcount',
'hexversion', 'maxint', 'modules', 'path', 'platform',
'prefix',
'ps1', 'ps2', 'setcheckinterval', 'setprofile',
'setrecursionlimit', 'settrace', 'stderr', 'stdin',
'stdout',
'version', 'version_info']

The information is built up from the __ dict __, __ methods __, and __ members __ attributes of the given object and may not be complete -- for example, methods and attributes inherited from other classes will not normally be included.

Notes for Perl programmers

Although there is no direct equivalent, the dir() function provides similar information to using keys() on a hash-based object, i.e.:

@attributes = keys %{ $objref};

although it doesn't list any methods, or using keys() on a package's symbol table:

@entities = keys %main::;
divmod(a, b) Perl equivalent: none

Returns a tuple containing the quotient and remainder of divided by b. For example:

>>> divmod(7,4)
(1, 3)

For integers the value returned is the same as a / b and a % b. If the values supplied are floating point numbers the result is (q, a % b), where q is usually math.floor(a / b) but may be 1 less than that. In any case q * b + a % b is very close to a, if a % b is non-zero it has the same sign as b, and 0 <= abs(a % b) < abs(b).

eval(expression [, globals [, locals ] ]) Perl equivalent: eval()

Evaluates the string expression, parsing and evaluating it as a standard Python expression. When called without any additional arguments the expression has access to the same global and local objects in which it is called. Alternatively, you can supply the global and local symbol tables as dictio-naries (see the globals() and locals() functions elsewhere in this chapter).

The return value is the value of the evaluated expression. For example:

>>> a = 99
>>> eval('divmod(a,7)')
(14,1)

Any syntax errors are raised as exceptions.

You can also use eval() to execute code objects, such as those created by the compile() function, but only when the code object has been compiled using the "eval" mode.

To execute arbitrary Python code incorporating statements as well as expressions, use the exec statement or use execfile() to dynamically execute a file.

Notes for Perl programmers

Although eval() appears to be identical to the Perl eval() function there are some differences:

  1. Python's eval() function is designed to evaluate an expression and return a value.

  2. Python's eval() can return an object, including a function or normal object type, rather than just a value or reference.

  3. Python's eval() is not designed to execute an arbitrary piece of any Python code (although it will) but just a simple expression, use the exec statement instead.

execfile(file [, globals [, locals ] ]) Perl equivalent: do, or require, or eval()

Identical to the exec statement, except that it executes statements from a file instead from a string. The globals and locals arguments should be dictionaries containing the symbol tables that will be available to the file during execution. If locals, is omitted then all references use the globals namespace. If both are omitted, then the file has access to the current symbol tables as at the time of execution.

Notes for Perl programmers

The execfile() function most closely matches Perl's eval() function in that it will execute a file of code as if the code was executed within the realms of the current interpreter instance, with access to the same functions and variables. However, if you supply your own globals or locals dictionaries then it can function as an alternative to Perl's Safe module for executing code within a fixed environment.

filter(function, list) Perl equivalent: grep() or map()

Filters the items in list according to whether function returns true, returning the new list. For example:

a = [1,2,3,4,5,6,7,8,9]
b = filter(lambda x: x > 6, a)
print b

If function is None, then the identity function is used and all the elements in list which are false are removed instead.

Notes for Perl programmers

The filter() function is a general purpose equivalent of the Perl grep() function. If you are looking for an alternative to Perl's grep() function consider using the example below:

def grep(pattern,list):
    import re
    retlist = []
    regex = re.compile(pattern)
    for element in list:
        if (regex.search(element)):
            retlist.append(element)
    return retlist
float(x) Perl equivalent: none

Converts x, which can be a string or number, to a floating point number.

getattr(object, name [, default ]) Perl equivalent: none

Returns the value of the attribute name of the object object. Syntactically the statement

getattr(x,'myvalue')

is identical to

x.myvalue

If name does not exist then the function returns default if supplied, or raises AttributeError otherwise.

Notes for Perl programmers

Because Perl's object system is based on the core scalar, array, and hash data types we can access an objects attribute pragmatically simply by supplying the variable name when accessing the array or hash element, for example:

$attribute = $object[$var];
$attribute = $object{$var};

However, we can't do this in Python -- you must use getattr(). The above lines are equivalent to:

attribute = getattr(object, var)
globals() Perl equivalent: none

Returns a dictionary representing the current global symbol table. This is always the dictionary of the current module -- if called within a function or method then it returns the symbol table for the module where the function or method is defined, not the function from where it is called.

Notes for Perl programmers

The globals() function is normally used in conjunction with the exec statement and the eval() and execfile() functions, among others. The closest equivalent in Perl is to access the symbol tables directly:

@globals = keys %main::;
hasattr(object, name) Perl equivalent: exists() or defined() to determine data, or UNIVERSAL::can(METHOD) to check for a particular method

Returns true if the object has an attribute matching the string name. Returns zero otherwise.

Notes for Perl programmers

This is the Python equivalent of the Perl exists() method, but it also follows the inheritance tree, functionality only available in Perl through the universal can() method.

hash(object) Perl equivalent: none

Returns the integer hash value for an object. The hash value is the same for any two objects that compare equally. Not applicable to mutable objects.

hex(x) Perl equivalent: printf("%x",$scalar

Converts an integer number to a hexadecimal string that is a valid Python expression.

Notes for Perl programmers

This is the opposite of the Perl hex() function which converts a hexadecimal or octal string to it's integer equivalent. The Python hex() function is equivalent to:

printf("%x",$value);
id(object) Perl equivalent: none

Returns an integer (or long integer) -- the identity -- which is guaranteed to be unique and constant during the lifetime of the object.

input( [prompt ]) Perl equivalent: read() or sysread()

Equivalent to eval(raw_input(prompt)). See raw_input() in this chapter for more information.

Notes for Perl programmers

This is the equivalent of the Term::Readline::readline() function/ method.

int(x [, radix ]) Perl equivalent: int(), hex(), oct()

Converts the number or string x to a plain integer. The radix argument if supplied is used as the base to use for the conversion and should be an integer in the range 2 to 36.

intern(string) Perl equivalent: none

Adds string to the table of "interned" strings, returning the interned version. Interned strings are available through a pointer, rather than raw string, allowing lookups of dictionary keys to be made using pointer rather than string comparisons. This provides a small performance gain over the normal string comparison methods.

Names used within the Python namespace tables and the dictionaries used to hold module, class or instance attributes are normally interned to aid the speed of execution of the script.

Interned strings are not garbage collected, so be aware that using interned strings on large dictionary key sets will increase the memory requirement significantly, even after the dictionary keys have gone out of scope.

isinstance(object, class) Perl equivalent: UNIVERSAL::isa()

Returns true if object is an instance of class. Determination will follow the normal inheritance rules and subclasses. You can also use the function to identify if object is of a particular type by using the type class definitions in the types module. If class is not a class or type object then a TypeError exception is raised.

issubclass(class1, class2) Perl equivalent: UNIVERSAL::isa()

Return true if class1 is a subclass of class2. A class is always considered as a subclass of itself. A TypeError exception is raised if either argument is not a class object.

len(s) Perl equivalent: length(), scalar @array, scalar keys %hash

Returns the length of a sequence (string, tuple, or list) or dictionary object.

Notes for Perl programmers

The Python len() function works for all sequence-based objects, so we can rewrite the following Perl code:

$length = length($string);
$length = scalar @array;

in Python as:

length = len(string)
length = len(array)
list(sequence) Perl equivalent: The qw// or () operators, or split('',$string)

Returns a list whose items and order are the same as those in sequence. For example:

>>> list('abc')
['a', 'b', 'c']
>>> list([1,2,3])
[1, 2, 3]
Notes for Perl programmers

Because Python strings are sequences of individual characters, Python can convert a single sequence of characters into a list (or tuple) of individual characters.

locals() Perl equivalent: none

Returns a dictionary representing the current local symbol table.

long(x) Perl equivalent: int()

Converts a string or number to a long integer. Conversion of a floating point number follows the same rules as int().

map(function, list, ) Perl equivalent: map()

Applies function to each item of list and returns the new list. For example:

>>> a = [1,2,3,4]
>>> map(lambda x: pow(x,2), a)
[1,4,9,16]

If additional lists are supplied then they are supplied to function in parallel. Lists are padded with None until all lists are of the same length.

If function is None then the identity function is assumed, causing map() to return list with all false arguments removed. If the function is None and multiple list arguments are supplied then a list of tuples of each argument of the list is returned, for example:

>>> map(None, [1,2,3,4], [4,5,6,7])
[(1, 4), (2, 5), (3, 6), (4, 7)]

The result is identical to that produced by the zip() function.

Notes for Perl programmers

The operation of the Python map() is identical to the Perl map() except for the treatment of multiple lists. In Perl, the following statement would apply function to each item in the remaining arguments to the function, just as if the arguments had been concatenated into a new list:

@chars = map(chr,(@list, $scalar, @array));

Trying the same in Python would result in chr() being passed as three arguments instead of one. Instead, concatenate the strings:

chars = map(lambda x: chr(x), list+scalar+array)

Also be aware that unless the function is predefined, you will have to use lambda to create an anonymous function. This is because Python doesn't have an equivalent to the $_ 'scratchpad' variable.

max(s [, args ]) Perl equivalent: none

When supplied with a single argument, returns the maximum value in the sequence s. When supplied a list of arguments, returns the largest argument from those supplied. See min() for more details.

min(s [, args ]) Perl equivalent: none

When supplied with a single argument, returns the minimum value in the sequence s. When supplied a list of arguments, returns the smallest value from all the arguments. Note that sequences in a multi-argument call are not traversed -- each argument is compared as a whole, such that:

min([1,2,3],[4,5,6])

returns:

[1, 2, 3]

And not the often expected 1.

oct(x) Perl equivalent: printf("%o",$scalar)

Converts an integer number to an octal string. The result is a valid Python expression. For example:

>>> oct(2001)
'03721'

Note that the returned value is always unsigned, such that oct(-1) will yield "037777777777" on a 32 bit machine.

Note for Perl programmers

This is not the same as the Perl oct() function -- this returns an octal number, it does not convert an octal string back to an integer.

open(filename [, mode [, bufsize ] ])

Perl equivalent: open() or sysopen()

Opens the file identified by filename, using the mode mode and buffering type bufsize. Returns a file object (see Chapters 3 and 6 for more information).

The mode is the same as that used by the system fopen() function -- see Table 8.2 for a list of valid modes. If mode is omitted then it defaults to r.

Table 8.2. File modes for the open() function
Mode Meaning
r Reading
w Writing
a Appending (file position automatically seeks to the end during the open)
r+ Open for updating (reading and writing)
w+ Truncates (empties) the file and then opens it for reading and writing
a+ Opens the file for reading and writing, automatically changes current file position to the end of the file
b When appended to any option opens the file in binary rather than text mode (Windows, DOS and some other OS unaffected)

The optional bufsize argument determines the size of the buffer to use while reading from the file. The different values supported are listed in Table 8.3 . If omitted, the system default is used.

For example, to open a file for reading in binary mode using a 256 character buffer:

myfile = open('myfile.txt','rb', 256);
Table 8.3. Buffer sizes supported by the open() function
Bufsize value Description
0 Disable buffering
1 Line buffered
>1 Use a buffer that is approximately bufsize characters in length
<0 Use the system default (line buffered for tty devices and fully buffered for any other file
Notes for Perl programmers

See Table 8.4 for the Python equivalents of the Perl file opening formats.

Table 8.4. Python and Perl file opening formats
Perl format Python mode
"" or "<file" r
">file" w
">>file" a
"+<file" r+
"+>file" w+
"+>>file" a+

The "b" option when opening a file is the equivalent of using binmode:

open(DATA, $file);
binmode DATA

The buffer option is far more extensive than Perl's. The Perl fragment:

open(DATA, 'myfile.txt');
autoflush DATA 1;

is equivalent to:

myfile=open('myfile.txt','r',0);
ord(c) Perl equivalent: ord()

Returns the ASCII or Unicode numeric code of the string of one character c. This is the inverse of chr() and unichr().

pow(x, y [, z ]) Perl equivalent: x**y

Returns the value of raised to the power of y. If is supplied then calculate raised to the power modulo z, calculated more efficiently than using:

pow(x,y) % z

The supplied arguments should be numeric types, and the types supplied determine the return type. If the calculated value cannot be represented by the supplied argument types then an exception is raised. For example, the following will fail:

pow(2,-1)

But:

pow(2.0,-1)

is valid.

Note for Perl programmers

To protect yourself from accidentally supplying the wrong number type to pow(), you might want to consider using the float() function:

pow(float(mynumber),-1)
range( [start, ] stop [, step ]) Perl equivalent: none

Returns a list of numbers starting from start and ending before stop using step as the interval. All numbers should be supplied and are returned as plain integers. If step is omitted then the step value defaults to one. If start is omitted then the sequence starts at zero. Note that the two arguments form of the call assumes that start and stop are supplied -- if you want to specify a step you must supply all three arguments.

For positive values of step:

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(5,10)
[5, 6, 7, 8, 9]
>>> range(5,25,5)
[5, 10, 15, 20]

Note that the final number is stop -- step, the range goes up to, but not including, the stop value.

If you supply a negative value to step then the range counts down, rather than up, and stop must be lower than start otherwise the returned list will be empty. For example:

>>> range(10,0,-1)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> range (25,0,-5)
[25, 20, 15, 10, 5]
>>> range(0,10,-1)
[]
Notes for Perl programmers

The Python range() function gets round the limitation of the Perl .. range operator allowing you to create your own range with a suitable step in both ascending and descending order. Be aware however that the Python range() and xrange() functions return a list up to but not including the final value, unlike the Perl range operator.

raw_input([prompt ]) Perl equivalent: read() or sysread() on STDIN or Term::Readline::readline()

Accepts raw input from sys.stdin, returning a string. Input is terminated by a newline, and this is stripped before the string is returned to the caller. If prompt is supplied, then it is output to sys.stdout without a trailing newline and used as the prompt for input. For example:

>>> name = raw_input('Name? ')
Name? Martin

If the readline module has been loaded then features such as line editing and history are supported during input.

Note for Perl programmers

Note that Python automatically strips the newline or carriage return character for you, you do not need to manually remove the line termination.

reduce(function, sequence [, initializer ]) Perl equivalent: none

Applies the function (supporting two arguments) cumulatively to each element of sequence, reducing the entire statement to a single value. For example, to emulate the (factorial) mathematical operator:

reduce(lambda x,y: x*y, [1,2,3,4,5])

the effect is to perform the calculation:

((((1*2)*3)*4)*5)

which equals 120.

If initializer is supplied then it's used as the first element in the sequence:

>>> reduce(lambda x,y: x*y, [1,2,3,4,5],10)
1200
reload(module) Perl equivalent: no direct equivalent, but you can use eval()

Reloads an already imported module. The reload includes the normal parsing and initializing processes employed when the module was imported originally. This allows you to reload a Python module without needing to exit the interpreter.

There are a number of caveats for using reload():

repr(object) Perl equivalent: Data::Dumper

Returns a string representation of object. This is identical to using backquotes on an object or attribute. The string returned would yield an object with the same value as that when passed to eval().

Notes for Perl programmers

Both the `` operator and the repr() function generate a printable form of any object and also simultaneously create a textual representation that can be evaluated. This can be useful in situations such as configuration files where you want to output a textual version of a particular object or variable that can be re-evaluated.

round(x[, n ]) Perl equivalent: sprintf()

Returns the floating point value rounded to n digits after the decimal point. Rounds to nearest whole number if is not specified. For example:

>>> round(0.4)
0.0
>>> round(0.5)
1.0
>>> round(-0.5)
-1.0
>>> round(3.14159264,2)
3.14
>>> round(1985,-2)
2000.0

As you can see, a negative number rounds to that many places before the decimal point. Also note that rounding is handled strictly on the point described by n, that is:

>>> round(1945,-1)
1950.0
>>> round(1945,-2)
1900.0

In the second example the "4" in 1945 is rounded to the next nearest, resulting in 1900, rather than rounding the "5" to make 1950 and then rounding 1950 up to 2000.

setattr(object, name, value) Perl equivalent: none

Sets the attribute name of object to value. The opposite of the getattr() function which merely gets the information. The statement:

setattr(myobj, 'myattr', 'new value')

is equivalent to:

myobj.myattr = 'new value'

but can be used in situations where the attribute is known pragmatically by name, rather than explicitly as an attribute.

Note for Perl programmers

The setattr() function gets round the limitation of soft references and hash- or array-based objects used in Perl. In Perl you would be able to use:

$object{'myattr'}  = $value;

Python does not support soft or symbolic references, the statement:

object.'myattr' = value

is invalid.

slice( [start, ] stop [, step ]) Perl equivalent: none

Returns a slice object representing the set of indices specified by range(start, stop, step). If one argument is supplied then it's used as stop, two arguments imply start and stop. The default value for any unsupplied argument is None. Slice objects have three attributes ( start, stop, step ) which merely return the corresponding argument supplied to the slice() function during the object's creation.

str(object) Perl equivalent: none, although Data::Dumper will show information for some objects

Returns a string representation of object. This is similar to the repr() function except that the return value is designed to be a printable string, rather than a string that is compatible with the eval function.

tuple(sequence) Perl equivalent: none

Returns a tuple whose items are the same and in the same order as the items in sequence. Examples:

>>> tuple('abc')
('a', 'b', 'c')
>>> tuple([1,2,3])
(1, 2, 3)
type(object) Perl equivalent: the ref() function returns the base object type or its class

Returns the type of object. The return value is a type object, as described by the types module. For example:

>>> import types
>>> if type(string) == types.StringType:
    print "This is a string"
Notes for Perl programmers

The return value from type can be printed, for example:

>>> a = 1
>>> print type(a)
<type 'int'>

in the same way as the output from the Perl ref() function. However, it's more practical to compare the value to one of those in the types module if you are looking for a specific type. The full list of types supported by the types module is listed below:

BufferType BuiltinFunctionType BuiltinMethodType
ClassType CodeType ComplexType
DictType DictionaryType EllipsisType
FileType FloatType FrameType
FunctionType InstanceType IntType
LambdaType ListType LongType
MethodType ModuleType NoneType
SliceType StringType TracebackType
TupleType TypeType UnboundMethodType
UnicodeType XRangeType

unichr(i) Perl equivalent: the Perl chr() function natively decodes Unicode characters

Returns a Unicode string of one character whose code is the integer -- this is the Unicode equivalent of the chr() function described earlier in this chapter. Note that to convert a Unicode character back into its integer form you use ord(), there is no uniord() function. A ValueError exception is raised if the integer supplied is outside the range 0. to 65535.

Notes for Perl programmers

Note that you must use the unichr() function if want to encode a Unicode character, the Python chr() function does not understand Unicode characters. However, the Python ord() function does decode them.

unicode(string [, encoding [, errors ] ]) Perl equivalent: none, Perl automatically decodes Unicode strings natively

Decodes the Unicode string using the codec encoding. The default behavior (when encoding is not supplied) is to decode UTF-8 in strict mode, errors raising ValueError. See the codecs module for a list of suitable codecs.

vars( [object ]) Perl equivalent: similar to accessing the symbol table directly using %main::

Returns a dictionary corresponding to the current local symbol table. When supplied with a module, class, or class instance, returns a dictionary corresponding to that object's symbol table. Does not modify the returned dictionary as the effects are undefined. xrange( [start, ] stop [, step ])

Perl equivalent: none

Works in the same way as the range() function, except that it returns an xrange object. An xrange object is an opaque object type which returns the same information as the list requested, without having to store each individual element in the list. This is particularly useful in situations where you are creating very large lists, the memory saved by using xrange() over range() can be considerable.

Notes for Perl programmers

The xrange() function gets around the similar problem in Perl of creating very large lists which are used for iteration in a loop. For example, in Perl it's a bad idea to do:

foreach $count (1..100000)

Instead we'd do:

for($count = 1;$count<=100000;$count++)

In Python the temptation is to use:

foreach count in range(1,100000):

However, it's more efficient to use:

foreach count in xrange(1,100000):
zip(seq1, ) Perl equivalent: none

Takes a series of sequences and returns them as a list of tuples, where each tuple contains the th element of each of the supplied sequences. For example:

>>> a = [1,2,3,4]
>>> b = [5,6,7,8]
>>> zip(a,b)
[(1, 5), (2, 6), (3, 7), (4, 8)]

[Nov 09, 2017] Conversion of Perl to Python

Nov 09, 2017 | stackoverflow.com

I think you should rewrite your code. The quality of the results of a parsing effort depends on your Perl coding style. I think the quote below sums up the theoretical side very well. From Wikipedia: Perl in Wikipedia

Perl has a Turing-complete grammar because parsing can be affected by run-time code executed during the compile phase.[25] Therefore, Perl cannot be parsed by a straight Lex/Yacc lexer/parser combination. Instead, the interpreter implements its own lexer, which coordinates with a modified GNU bison parser to resolve ambiguities in the language.

It is often said that "Only perl can parse Perl," meaning that only the Perl interpreter (perl) can parse the Perl language (Perl), but even this is not, in general, true. Because the Perl interpreter can simulate a Turing machine during its compile phase, it would need to decide the Halting Problem in order to complete parsing in every case. It's a long-standing result that the Halting Problem is undecidable, and therefore not even Perl can always parse Perl. Perl makes the unusual choice of giving the user access to its full programming power in its own compile phase. The cost in terms of theoretical purity is high, but practical inconvenience seems to be rare.

Other programs that undertake to parse Perl, such as source-code analyzers and auto-indenters, have to contend not only with ambiguous syntactic constructs but also with the undecidability of Perl parsing in the general case. Adam Kennedy's PPI project focused on parsing Perl code as a document (retaining its integrity as a document), instead of parsing Perl as executable code (which not even Perl itself can always do). It was Kennedy who first conjectured that, "parsing Perl suffers from the 'Halting Problem'."[26], and this was later proved.[27]

Starting in 5.10, you can compile perl with the experimental Misc Attribute Decoration enabled and set the PERL_XMLDUMP environment variable to a filename to get an XML dump of the parse tree (including comments - very helpful for language translators). Though as the doc says, this is a work in progress.

Looking at the PLEAC stuff, what we have here is a case of a rote translation of a technique from one language causing another to look bad. For example, its rare in Perl to work character-by-character. Why? For one, its a pain in the ass. A fair cop. For another, you can usually do it faster and easier with a regex. One can reverse the OP's statement and say "in Perl, regexes are so easy that most of the time other string manipulation is not needed". Anyhow, the OP's sentiment is correct. You do things differently in Perl than in Python so a rote translator would produce nasty code. – Schwern Apr 8 '10 at 11:47

down vote Converting would require writing a Perl parser, semantic checker, and Python code generator.

Not practical. Perl parsers are hard enough for the Perl teams to get right. You'd be better off translating Perl to Python from the Perl AST (opcodes) using the Perl Opcode or related modules.

http://perldoc.perl.org/Opcode.html

Some notations do not map from Perl to Python without some work. Perl's closures are different, for example. So is its regex support.

In short, either convert it by hand, or use some integration modules to call Python from Perl or vice-versa

[Nov 02, 2001] Perl to Python Migration by Martin C. Brown

Martin C Brown is the author of several books on Perl (including Debugging Perl) and a book on Python (Python The Complete Reference, 2001) so he knows both languages. which makes the book pretty unique. there is no other books that cover Python from the position of Perl programmer.
My conclusion

Python is an excellent language for my intended use. It is a good language for many of the applications that one would use Lisp as a rapid prototyping environment for. The three main drawbacks are (1) execution time is slow, (2) there is very little compile-time error analysis, even less than Lisp, and (3) Python isn't called "Java", which is a requirement in its own right for some of my audience. I need to determine if JPython is close enough for them.

Python can be seen as either a practical (better libraries) version of Scheme, or as a cleaned-up (no $@&%) version of Perl.

While Perl's philosophy is TIMTOWTDI (there's more than one way to do it), Python tries to provide a minimal subset that people will tend to use in the same way. One of Python's controversial features, using indentation level rather than begin/end or {/}, was driven by this philosophy: since there are no braces, there are no style wars over where to put the braces. Interestingly, Lisp has exactly the same philosophy on this point: everyone uses emacs to indent their code.

If you deleted the parens on control structure special forms, Lisp and Python programs would look quite similar.

Python has the philosophy of making sensible compromises that make the easy things very easy, and don't preclude too many hard things. In my opinion it does a very good job. The easy things are easy, the harder things are progressively harder, and you tend not to notice the inconsistencies. Lisp has the philosophy of making fewer compromises: of providing a very powerful and totally consistent core.

This can make Lisp harder to learn because you operate at a higher level of abstraction right from the start and because you need to understand what you're doing, rather than just relying on what feels or looks nice.

But it also means that in Lisp it is easier to add levels of abstraction and complexity; Lisp makes the very hard things not too hard.

#132)
(User Info)

Python is a really clean and elegant interpreted OO language. I don't think many folks will argue that Perl is the same.

Well, Python was OO from the ground up and Perl was not, and it shows. But as far as elegance is concerned, it is rather in the eye of the beholder.

The fact that there are many compact ways to solve the same problem was a goal of Perl, and it is hard to imagine a language which achieves this to a higher degree. In that sense, you have to grant that Perl does what it sets out to do brilliantly.

I think of Perl as a radical language and Python as a rather conservative: it takes conventional notions of what is needed in a language to efficiently support a programming project and pares away everything that is unnecessary baggage. Perl, at least my take on it, rejects at the outset that there is any one way to support a programming project and encourages the programmer to adopt whatever stance works to solve the problem.

The interesting thing is that for me the common juxtaposition of Perl and Python makes more sense than you'd think at the outset. I've tried my hand at each for projects, and I don't find I'm particularly more productive in one than the other. Perhaps Perl has a slight edge because I've been using it longer, and most of the projects I've tried are typical of the classic Perl problem space of Practical Extraction and Reporting.

I don't really find one language to be more maintainable than the other; perhaps Python restricts certain bad habits that Perl permits, but in reality efficient and sensible problem decomposition and program organization are rather more important. Perhaps the flavor of bad programming varies somewhat between the languages -- bad Perl is dense and indigestible, bad Python is bland and undifferentiated.

Recommended Links

Google matched content

Softpanorama Recommended

Top articles

Sites



Etc

Society

Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy

Quotes

War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes

Bulletin:

Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law

History:

Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D


Copyright © 1996-2018 by Dr. Nikolai Bezroukov. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) in the author free time and without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to make a contribution, supporting development of this site and speed up access. In case softpanorama.org is down you can use the at softpanorama.info

Disclaimer:

The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.

The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: November, 23, 2019