[Tutor] translating some python code to perl
Danny Yoo
dyoo at hkn.eecs.berkeley.edu
Thu Aug 28 18:42:10 EDT 2003
On Thu, 28 Aug 2003, Lloyd Kvam wrote:
> This did not generate any responses, but I thought I'd post my solution
> anyway.
>
> #!/usr/bin/perl
> # testhash.pl
>
> %d1 = (
> '1' => 'one',
> '2' => 'two',
> 'd2' => {'nest1' => 'nest one',
> 'nest2' => 'nest two',}
> );
>
> print "\nlookup 1 in d1: $d1{'1'}\n";
> print "\nlookup d2 within d1: $d1{'d2'}\n";
> print "\nlookup nest1 in d2 within d1: $d1{'d2'}{'nest1'}\n";
> #############
> There's probably a better way, but this seems to work. The initial
> variable name is prefixed with a % rather than the usual $ and the
> hash is delimited with parentheses.
Hi Lloyd,
Yes. In Perl, there's a distinction between a "hash" and a "hash
reference". In Python, there's no such distinction, so technically, that
means that if we're trying to convert something like:
d1 = {'1' : 'one',
'2' : 'two',
'd2': {'nest1': 'nest one',
'nest2': 'nest two',
},
'3' : 'four',
'd3': {'nest3': 'nest three',
'nest4': 'nest four'
},
}
then our emitted Perl code should be something like:
$d1 = {'1' => 'one',
'2' => 'two',
'd2' => {'nest1' => 'nest one',
'nest2' => 'nest two',
},
'3' => 'four',
'd3' => {'nest3': 'nest three',
'nest4': 'nest four'
},
}
> My python code (version 2.2) follows:
> #!/usr/bin/python
> # py2perl.py
> '''module to handle some python to perl transformations.
> '''
> class Py2perl_dict(dict):
>
> def __init__(self, arg):
> super(Py2perl_dict, self).__init__(arg)
> for key,val in self.items():
> if isinstance(val, dict) and not isinstance(val, Py2perl_dict):
> self[key] = Py2perl_dict(val)
>
> def __repr__(self):
> keylist = self.keys()
> keylist.sort()
> return ''.join(['{',
> ','.join(["%s => %s" % (repr(key),repr(self[key])) for key in keylist]),
> '}'])
This code works, but also does modifications to our original dictionary.
Seems a harsh price to pay for compatibility. *grin*
Here's an alternative approach:
###
def renderObject(obj):
if isinstance(obj, dict):
return renderDictionary(obj)
if isinstance(obj, str):
return renderString(obj)
raise Exception, ("I don't know how to handle %s" % obj)
def renderDictionary(d):
rendered_items = []
for key, value in d.items():
rendered_items.append("%s => %s" % (renderObject(key),
renderObject(value)))
return ("{\n%s\n}" % indent(",\n".join(rendered_items)))
def renderString(s):
return repr(s)
def indent(s):
indented_lines = [' ' + l for l in s.split('\n')]
return '\n'.join(indented_lines)
###
Here's what it looks like when we apply this to our 'd1' dictionary:
###
>>> print renderObject(d1)
{
'1' => 'one',
'3' => 'four',
'2' => 'two',
'd2' => {
'nest2' => 'nest two',
'nest1' => 'nest one'
},
'd3' => {
'nest4' => 'nest four',
'nest3' => 'nest three'
}
}
###
Hope this helps!
More information about the Tutor
mailing list