From: tim_one at email.msn.com (Tim Peters)
Date: Sun, 25 Apr 1999 17:29:34 -0400
Subject: converting perl to python - simple questions.
In-Reply-To: <7fvstg$nqo$1@nnrp1.dejanews.com>
Message-ID: <000101be8f62$b66e4700$669e2299@tim>
Content-Length: 2963
X-UID: 470                                                  

[sweeting at neuronet.com.my]

[Perl "exists"/"defined" vs Python "None"]
> For years, I've been thinking of "None" in Python as "null" in javascript,
> meaning "no value set"

Really not the same!

> and so it was actually quite interesting to see that Perl has "exists"
> and "defined" functions for dictionaries....

Perl is much more reluctant than Python to raise errors, and tends to return
"the undefined value" in situations where Python would kick you.  So e.g.

%d = ();

($d{'hasa'}) = ('cat' =~ /(a)/);
print exists $d{'hasa'} ? "exists" : "not exists", "\n";
print defined $d{'hasa'} ? "defined" : "not defined", "\n";

($d{'hasa'}) = ('dog' =~ /(a)/);
print exists $d{'hasa'} ? "exists" : "not exists", "\n";
print defined $d{'hasa'} ? "defined" : "not defined", "\n";
print 2 + $d{'hasa'}, "\n";

prints:

exists
defined
exists
not defined
2

I'd rather get kicked <0.1 wink>.  To be fair, adding 2 to the undefined
value will print a "use of uninitialized value" warning if Perl is run
with -w.  I'd still rather get kicked.  (BTW, always run Perl with -w!  Even
Perl-heads will advise that <wink>.  If the script you're translating relies
on extreme Perlish subtleties, -w will probably alert you to them.)

>> Get in the habit of using r-strings for writing regexps;
>> they'll make your backslash life much easier.

> Thank you for pointing that out - the perl stuff's been screwing
> with my head and making me confused, \s being ok in that language.

That's the problem!  \s is fine in a Python string too.  But other things
aren't, and without using r-strings you're responsible for remembering which
is which.  For example, the regexp

    r"\bthe"

matches "the" starting at a word boundary, but the regexp

    "\bthe"

matches "the" following a backspace character.

Perl actually has the same problem, but it's *usually* hidden by "regexp
context"; e.g.;

    $string =~ /\bthe/

matches "the" starting at a word boundary, while

    $pattern = "\bthe";
    $string =~ /$pattern/

matches "the" following a backspace character.  Perl treats string escape
sequences differently depending on whether the string is or isn't in regexp
context; Python has no concept of context, so always treats string escapes
the same way; the feature of Python r-strings is that they don't do *any*
backslash substitutions, allowing the callee (in this case, re and pcre) to
treat them as *it* wants to.

Subtleties aside, most Perl5 regexps work fine in Python after replacing the
bracketing / and / with r" and ".  OTOH, if you can use a facility from the
string module instead, it's usually clearer and faster; e.g., the original

    $x !~ /^\s$/

may be better as

    not (len(x) == 1 and x in string.whitespace)

depending on what the original line is *really* trying to do (did they
really want all of " ", "\n", " \n", and "\n\n" to match?  beats me ... and
that's one reason a string version is clearer).

all-bleeding-stops-ly y'rs  - tim






