|
perl (1987)
|
python (1991)
|
基础
|
模块导入
|
use strict;
|
import os, re, sys
|
版本查看
|
$ perl -v
|
$ python -V
|
执行脚本
|
$ perl foo.pl
|
$ python foo.py
|
交互模式
|
$ perl -de 0
|
$ python
|
执行语句
|
$ perl -e 'print("hi\n")'
|
$ python -c "print('hi')"
|
语句分隔
|
;
|
\n (newline) or ;
|
语句块
|
{}
|
Indent
|
注释
|
# comment
|
# comment
|
多行注释
|
=for comment line another line =cut
|
use triple quote string literal: '''comment line another line'''
|
变量和操作符
|
赋值
|
$v = 1;
|
v = 1
|
赋值
|
($x, $y, $z) = (1, 2, 3); # 3 is discarded: ($x, $y) = (1, 2, 3); # $z set to undef: ($x, $y, $z) = (1, 2);
|
x, y, z = 1, 2, 3 # raises ValueError: x, y = 1, 2, 3 # raises ValueError: x, y, z = 1, 2
|
交换
|
($x, $y) = ($y, $x);
|
x, y = y, x
|
操作符
|
+= -= *= none /= %= **= .= x= &&= ||= ^= <<= >>= &= |= ^=
|
# do not return values: += -= *= /= //= %= **= += *= &= |= ^= <<= >>= &= |= ^=
|
自增
|
my $x = 1; my $y = ++$x; my $z = --$y;
|
none
|
局部变量
|
my $v; my (@a, %d); my $x = 1; my ($y, $z) = (2, 3);
|
# in function body: v = None a, d = [], {} x = 1 y, z = 2, 3
|
全局变量
|
our ($g1, $g2) = (7, 8); sub swap_globals { ($g1, $g2) = ($g2, $g1); }
|
g1, g2 = 7, 8 def swap_globals(): global g1, g2 g1, g2 = g2, g1
|
常量
|
use constant PI => 3.14;
|
# uppercase identifiers # constant by convention PI = 3.14
|
空
|
undef
|
None
|
空测试
|
! defined $v
|
v == None v is None
|
访问未定义变量
|
error under use strict; otherwise undef
|
raises NameError
|
真假
|
1 ""
|
True False
|
假
|
undef 0 0.0 "" "0" ()
|
False None 0 0.0 '' [] {}
|
逻辑运算
|
&& || ! lower precedence: and or xor not
|
and or not
|
条件
|
$x > 0 ? $x : -$x
|
x if x > 0 else -x
|
比较
|
numbers only: == != > < >= <= strings: eq ne gt lt ge le
|
comparison operators are chainable: == != > < >= <=
|
数学运算
|
类型转化
|
7 + "12" 73.9 + ".037" "value: " . 8
|
7 + int('12') 73.9 + float('.037') 'value: ' + str(8)
|
算术运算
|
+ - * / none % **
|
+ - * / // % **
|
取余
|
int ( 13 / 5 ) none
|
13 // 5 q, r = divmod(13, 5)
|
浮点除法
|
13 / 5
|
float(13) / 5 # Python 3: 13 / 5
|
数学函数
|
use Math::Trig qw( tan asin acos atan);
sqrt exp log sin cos tan asin acos atan atan2
|
from math import sqrt, exp, log, \ sin, cos, tan, asin, acos, atan, atan2
|
四舍五入
|
# cpan -i Number::Format use Number::Format 'round'; use POSIX qw(ceil floor);
int($x) round($x, 0) ceil($x) floor($x) abs($x)
|
import math
int(x) int(round(x)) math.ceil(x) math.floor(x) abs(x)
|
最大最小
|
use List::Util qw(min max);
min(1,2,3); max(1,2,3); @a = (1,2,3); min(@a); max(@a);
|
min(1,2,3) max(1,2,3) min([1,2,3]) max([1,2,3])
|
除0
|
error
|
raises ZeroDivisionError
|
大整数
|
converted to float; use Math::BigInt to create arbitrary length integers
|
becomes arbitrary length integer of type long
|
大浮点数
|
inf
|
raises OverflowError
|
随机数
|
int(rand() * 100) rand() none
|
import random
random.randint(0,99) random.random() random.gauss(0,1)
|
随机数
|
srand 17;
my $sd = srand; srand($sd);
|
import random
random.seed(17) sd = random.getstate() random.setstate(sd)
|
位操作
|
<< >> & | ^ ~
|
<< >> & | ^ ~
|
其他进制
|
0b101010 052 0x2a
|
0b101010 052 0x2a
|
字符串操作
|
字符串
|
"don't say \"no\"" 'don\'t say "no"'
|
'don\'t say "no"' "don't say \"no\"" "don't " 'say "no"' '''don't say "no"''' """don't say "no\""""
|
多行字符串
|
yes
|
triple quote literals only
|
转义
|
double quoted: \a \b \cx \e \f \n \r \t \xhh \x{hhhh} \ooo Perl 5.14: \o{ooo}
single quoted: \' \\
|
single and double quoted: \newline \\ \' \" \a \b \f \n \r \t \v \ooo \xhh
Python 3: \uhhhh \Uhhhhhhhh
|
变量替换
|
my $count = 3; my $item = "ball"; print "$count ${item}s\n";
|
count = 3 item = 'ball' print(‘%s %s’ % (count, item))
|
sprintf
|
my $fmt = "lorem %s %d %f"; sprintf($fmt, "ipsum", 13, 3.7)
|
'lorem %s %d %f' % ('ipsum', 13, 3.7)
fmt = 'lorem {0} {1} {2}' fmt.format('ipsum', 13, 3.7)
|
here document
|
$word = "amet"; $s = <<EOF; lorem ipsum dolor sit $word EOF
|
‘’’ ‘’’
|
字符串连接
|
my $s = "Hello, "; my $s2 = $s . "World!";
|
s = 'Hello, ' s2 = s + 'World!'
juxtaposition can be used to concatenate literals: s2 = 'Hello, ' "World!"
|
字符串复制
|
my $hbar = "-" x 80;
|
hbar = '-' * 80
|
字符串分隔
|
split(/\s+/, "do re mi fa") split(/\s+/, "do re mi fa", 2) split(/(\s+)/, "do re mi fa"); split(//, "abcd")
|
'do re mi fa'.split() 'do re mi fa'.split(None, 1) re.split('(\s+)', 'do re mi fa') list('abcd')
|
字符串连接
|
join(" ", qw(do re mi fa))
|
' '.join(['do', 're', 'mi', 'fa'])
|
字符串大小写
|
uc("lorem") lc("LOREM") ucfirst("lorem")
|
'lorem'.upper() 'LOREM'.lower() 'lorem'.capitalize()
|
字符串strip
|
# cpan -i Text::Trim use Text::Trim;
trim " lorem " ltrim " lorem" rtrim "lorem "
|
' lorem '.strip() ' lorem'.lstrip() 'lorem '.rstrip()
|
字符串格式化
|
sprintf("%-10s", "lorem") sprintf("%10s", "lorem")
|
'lorem'.ljust(10) 'lorem'.rjust(10)
|
字符串长度
|
length("lorem")
|
len('lorem')
|
字符串index
|
index("lorem ipsum", "ipsum") rindex("do re re", "re") return -1 if not found
|
'do re re'.index('re') 'do re re'.rindex('re') raise ValueError if not found
|
子字符串
|
substr("lorem ipsum", 6, 5)
|
'lorem ipsum'[6:11]
|
访问字符串中字母
|
can't use index notation with strings: substr("lorem ipsum", 6, 1)
|
'lorem ipsum'[6]
|
字母数字转化
|
chr(65) ord("A")
|
chr(65) ord('A')
|
正则表达式
|
字符串或
|
/lorem|ipsum/ qr(/etc/hosts)
|
re.compile('lorem|ipsum') none
|
特殊字符
|
char class abbrevs: . \d \D \h \H \s \S \v \V \w \W
anchors: ^ $ \A \b \B \z \Z
|
char class abbrevs: . \d \D \s \S \w \W
anchors: ^ $ \A \b \B \Z
|
正则表达式匹配
|
if ($s =~ /1999/) { print "party!\n"; }
|
if re.search('1999', s): print('party!')
|
忽略大小写
|
"Lorem" =~ /lorem/i
|
re.search('lorem', 'Lorem', re.I)
|
选项
|
i m s p x
|
re.I re.M re.S re.X
|
替换
|
my $s = "do re mi mi mi"; $s =~ s/mi/ma/g;
|
s = 'do re mi mi mi' s = re.compile('mi').sub('ma', s)
|
group
|
$rx = qr/(\d{4})-(\d{2})-(\d{2})/; "2010-06-03" =~ $rx; ($yr, $mo, $dy) = ($1, $2, $3);
|
rx = '(\d{4})-(\d{2})-(\d{2})' m = re.search(rx, '2010-06-03') yr, mo, dy = m.groups()
|
findall
|
my $s = "dolor sit amet"; @a = $s =~ m/\w+/g;
|
s = 'dolor sit amet' a = re.findall('\w+', s)
|
匹配引用
|
"do do" =~ /(\w+) \1/
my $s = "do re"; $s =~ s/(\w+) (\w+)/$2 $1/;
|
none
rx = re.compile('(\w+) (\w+)') rx.sub(r'\2 \1', 'do re')
|
日期时间
|
日期时间类型
|
Time::Piece if use Time::Piece in effect, otherwise tm array
|
datetime.datetime
|
当前日期时间
|
use Time::Piece;
my $t = localtime(time); my $utc = gmtime(time);
|
import datetime
t = datetime.datetime.now() utc = datetime.datetime.utcnow()
|
与epoch转化
|
use Time::Local; use Time::Piece;
my $epoch = timelocal($t); my $t2 = localtime(1304442000);
|
from datetime import datetime as dt
epoch = int(t.strftime("%s")) t2 = dt.fromtimestamp(1304442000)
|
当前epoch
|
$epoch = time;
|
import datetime
t = datetime.datetime.now() epoch = int(t.strftime("%s"))
|
strftime
|
use Time::Piece;
$t = localtime(time); $fmt = "%Y-%m-%d %H:%M:%S"; print $t->strftime($fmt);
|
t.strftime('%Y-%m-%d %H:%M:%S')
|
默认格式
|
Tue Aug 23 19:35:19 2011
|
2011-08-23 19:35:59.411135
|
字符串转为时间strptime
|
use Time::Local; use Time::Piece;
$s = "2011-05-03 10:00:00"; $fmt = "%Y-%m-%d %H:%M:%S"; $t = Time::Piece->strptime($s,$fmt);
|
from datetime import datetime
s = '2011-05-03 10:00:00' fmt = '%Y-%m-%d %H:%M:%S' t = datetime.strptime(s, fmt)
|
解析日期
|
# cpan -i Date::Parse use Date::Parse;
$epoch = str2time("July 7, 1999");
|
# pip install python-dateutil import dateutil.parser
s = 'July 7, 1999' t = dateutil.parser.parse(s)
|
时间差
|
Time::Seconds object if use Time::Piece in effect; not meaningful to subtract tm arrays
|
datetime.timedelta object
|
时间运算
|
use Time::Seconds;
$now = localtime(time); $now += 10 * ONE_MINUTE() + 3;
|
import datetime
delta = datetime.timedelta( minutes=10, seconds=3) t = datetime.datetime.now() + delta
|
时区
|
Time::Piece has local timezone if created withlocaltime and UTC timezone if created with gmtime; tm arrays have no timezone or offset info
|
a datetime object has no timezone information unless a tzinfo object is provided when it is created
|
timezone name; offset from UTC; 是否夏令时
|
# cpan -i DateTime use DateTime; use DateTime::TimeZone;
$dt = DateTime->now(); $tz = DateTime::TimeZone->new( name=>"local");
$tz->name; $tz->offset_for_datetime($dt) / 3600; $tz->is_dst_for_datetime($dt);
|
import time
tm = time.localtime() time.tzname[tm.tm_isdst] (time.timezone / -3600) + tm.tm_isdst tm.tm_isdst
|
microseconds
|
use Time::HiRes qw(gettimeofday);
($sec, $usec) = gettimeofday;
|
t.microsecond
|
sleep
|
a float argument will be truncated to an integer: sleep 1;
|
import time
time.sleep(0.5)
|
timeout
|
eval { $SIG{ALRM}= sub {die "timeout!";}; alarm 5; sleep 10; }; alarm 0;
|
import signal, time
class Timeout(Exception): pass
def timeout_handler(signo, fm): raise Timeout()
signal.signal(signal.SIGALRM, timeout_handler)
try: signal.alarm(5) time.sleep(10) except Timeout: pass signal.alarm(0)
|
数组
|
定义
|
@a = (1, 2, 3, 4);
|
a = [1, 2, 3, 4]
|
quote words
|
@a = qw(do re mi);
|
none
|
长度
|
$#a + 1 or scalar(@a)
|
len(a)
|
空测试
|
!@a
|
not a
|
使用
|
$a[0]
|
a[0]
|
更新
|
$a[0] = "lorem";
|
a[0] = 'lorem'
|
越界访问
|
@a = (); evaluates as undef: $a[10]; increases array size to 11: $a[10] = "lorem";
|
a = [] raises IndexError: a[10] raises IndexError: a[10] = 'lorem'
|
index
|
use List::Util 'first';
@a = qw(x y z w); $i = first {$a[$_] eq "y"} (0..$#a);
|
a = ['x', 'y', 'z', 'w'] i = a.index('y')
|
子数组
|
select 3rd and 4th elements: @a[2..3] splice(@a, 2, 2)
|
select 3rd and 4th elements: a[2:4] none
|
子数组
|
@a[1..$#a]
|
a[1:]
|
添加删除
|
@a = (6,7,8); push @a, 9; pop @a;
|
a = [6,7,8] a.append(9) a.pop()
|
插入删除
|
@a = (6,7,8); unshift @a, 5; shift @a;
|
a = [6,7,8] a.insert(0,5) a.pop(0)
|
数组连接
|
@a = (1,2,3); @a2 = (@a,(4,5,6)); push @a, (4,5,6);
|
a = [1,2,3] a2 = a + [4,5,6] a.extend([4,5,6])
|
初始化
|
@a = (undef) x 10;
|
a = [None] * 10 a = [None for i in range(0, 10)]
|
浅拷贝深拷贝
|
use Storable 'dclone'
my @a = (1,2,[3,4]); my $a2 = \@a; my @a3 = @a; my @a4 = @{dclone(\@a)};
|
import copy
a = [1,2,[3,4]] a2 = a a3 = list(a) a4 = copy.deepcopy(a)
|
数组作为函数参数
|
each element passed as separate argument; use reference to pass array as single argument
|
parameter contains address copy
|
遍历
|
for $i (1, 2, 3) { print "$i\n" }
|
for i in [1,2,3]: print(i)
|
遍历
|
none; use range iteration from 0 to $#a and use index to look up value in the loop body
|
a = ['do', 're', 'mi', 'fa'] for i, s in enumerate(a): print('%s at index %d' % (s, i))
|
range
|
for $i (1..1_000_000) { code }
|
range replaces xrange in Python 3: for i in xrange(1, 1000001): code
|
range数组
|
@a = 1..10;
|
a = range(1, 11) Python 3: a = list(range(1, 11))
|
翻转
|
@a = (1,2,3); reverse @a; @a = reverse @a;
|
a = [1,2,3] a[::-1] a.reverse()
|
排序
|
@a = qw(b A a B); sort @a; @a = sort @a; sort { lc($a) cmp lc($b) } @a;
|
a = ['b', 'A', 'a', 'B'] sorted(a) a.sort() a.sort(key=str.lower)
|
去重复
|
use List::MoreUtils 'uniq';
my @a = (1,2,2,3); my @a2 = uniq @a; @a = uniq @a;
|
a = [1,2,2,3] a2 = list(set(a)) a = list(set(a))
|
是否存在于数组
|
7 ~~ @a
|
7 in a
|
集合交集
|
|
{1,2} & {2,3,4}
|
集合或
|
|
{1,2} | {2,3,4}
|
集合运算
|
|
{1,2,3} - {2} {1,2} ^ {2,3,4}
|
map
|
map { $_ * $_ } (1,2,3)
|
map(lambda x: x * x, [1,2,3]) # or use list comprehension: [x*x for x in [1,2,3]]
|
filter
|
grep { $_ > 1 } (1,2,3)
|
filter(lambda x: x > 1, [1,2,3]) # or use list comprehension: [x for x in [1,2,3] if x > 1]
|
reduce
|
use List::Util 'reduce';
reduce { $x + $y } 0, (1,2,3)
|
# import needed in Python 3 only from functools import reduce
reduce(lambda x, y: x+y, [1,2,3], 0)
|
All/any
|
# cpan -i List::MoreUtils use List::MoreUtils qw(all any);
all { $_ % 2 == 0 } (1,2,3,4) any { $_ % 2 == 0 } (1,2,3,4)
|
all(i%2 == 0 for i in [1,2,3,4]) any(i%2 == 0 for i in [1,2,3,4])
|
shuffle and sample
|
use List::Util 'shuffle';
@a = (1, 2, 3, 4); shuffle(@a); none
|
from random import shuffle, sample
a = [1, 2, 3, 4] shuffle(a) sample(a, 2)
|
zip
|
# cpan -i List::MoreUtils use List::MoreUtils 'zip';
@nums = (1, 2, 3); @lets = qw(a b c); # flat array of 6 elements: @a = zip @nums, @lets;
|
# array of 3 pairs: a = zip([1,2,3], ['a', 'b', 'c'])
|
字典对象
|
定义
|
%d = ( t => 1, f => 0 );
|
d = { 't':1, 'f':0 }
|
size
|
scalar(keys %d)
|
len(d)
|
lookup
|
$d{"t"}
|
d['t']
|
out-of-bounds behavior
|
%d = (); evaluates as undef: $d{"lorem"}; adds key/value pair: $d{"lorem"} = "ipsum";
|
d = {} raises KeyError: d['lorem'] adds key/value pair: d['lorem'] = 'ipsum'
|
is key present
|
exists $d{"y"}
|
'y' in d
|
delete entry
|
%d = ( 1 => "t", 0 => "f" ); delete $d{1};
|
d = {1: True, 0: False} del d[1]
|
from array of pairs, from even length array
|
@a = (1,"a",2,"b",3,"c"); %d = @a;
|
a = [[1,'a'], [2,'b'], [3,'c']] d = dict(a)
a = [1,'a',2,'b',3,'c'] d = dict(zip(a[::2], a[1::2]))
|
merge
|
%d1 = (a=>1, b=>2); %d2 = (b=>3, c=>4); %d1 = (%d1, %d2);
|
d1 = {'a':1, 'b':2} d2 = {'b':3, 'c':4} d1.update(d2) # {'a': 1, 'c': 4, 'b': 3}
|
invert
|
%to_num = (t=>1, f=>0); %to_let = reverse %to_num;
|
to_num = {'t':1, 'f':0} # dict comprehensions added in 2.7: to_let = {v:k for k, v in to_num.items()}
|
iteration
|
while ( ($k, $v) = each %d ) { code }
|
for k, v in d.iteritems(): code
Python 3: for k, v in d.items(): code
|
keys and values as arrays
|
keys %d values %d
|
d.keys() d.values()
Python 3: list(d.keys()) list(d.values())
|
default value, computed value
|
my %counts; $counts{'foo'} += 1
define a tied hash for computed values and defaults other than zero or empty string
|
from collections import defaultdict
counts = defaultdict(lambda: 0) counts['foo'] += 1
class Factorial(dict): def __missing__(self, k): if k > 1: return k * self[k-1] else: return 1
factorial = Factorial()
|
函数
|
函数申明
|
sub add { $_[0] + $_[1] }
sub add { my ($a, $b) = @_; $a + $b; }
|
def add(a, b): return a+b
|
函数调用
|
add(1, 2);
parens are optional: add 1, 2;
|
add(1, 2)
|
参数丢失
|
set to undef
|
raises TypeError
|
参数默认值
|
sub my_log { my $x = shift; my $base = shift // 10;
log($x)/log($base); }
my_log(42); my_log(42, exp(1));
|
import math
def my_log(x, base=10): return math.log(x)/math.log(base)
my_log(42) my_log(42, math.e)
|
变长参数
|
sub foo { if ( @_ >= 1 ) { print "first: $_[0]\n"; } if ( @_ >= 2 ) { print "last: $_[-1]\n"; } }
|
def foo(*a): if len(a) >= 1: print('first: ' + str(a[0])) if len(a) >= 2: print('last: ' + str(a[-1]))
|
命名参数
|
none
|
def fequal(x, y, **opts): eps = opts.get('eps') or 0.01 return abs(x - y) < eps
fequal(1.0, 1.001) fequal(1.0, 1.001, eps=0.1**10)
|
pass number or string by reference
|
sub foo { $_[0] += 1; $_[1] .= "ly"; }
my $n = 7; my $s = "hard"; foo($n, $s);
|
not possible
|
pass array or dictionary by reference
|
sub foo { $_[0][2] = 5; $_[1]{"f"} = -1; }
my @a = (1,2,3); my %d = ("t"=> 1, "f" => 0); foo(\@a, \%d);
|
def foo(x, y): x[2] = 5 y['f'] = -1
a = [1,2,3] d = {'t':1, 'f':0} foo(a, d)
|
return value
|
return arg or last expression evaluated
|
return arg or None
|
multiple return values
|
sub first_and_second { return ($_[0], $_[1]); } @a = (1,2,3); ($x, $y) = first_and_second(@a);
|
def first_and_second(a): return a[0], a[1]
x, y = first_and_second([1,2,3])
|
lambda declaration
|
$sqr = sub { $_[0] * $_[0] }
|
body must be an expression: sqr = lambda x: x * x
|
lambda invocation
|
$sqr->(2)
|
sqr(2)
|
function reference
|
my $func = \&add;
|
func = add
|
function with private state
|
use feature state;
sub counter { state $i = 0; ++$i; }
print counter() . "\n";
|
# state not private: def counter(): counter.i += 1 return counter.i
counter.i = 0 print(counter())
|
closure
|
sub make_counter { my $i = 0; return sub { ++$i }; } my $nays = make_counter; print $nays->() . "\n";
|
# Python 3: def make_counter(): i = 0 def counter(): nonlocal i i += 1 return i return counter
nays = make_counter()
|
generator
|
none
|
def make_counter(): i = 0 while True: i += 1 yield i
nays = make_counter() print(nays.next())
|
decorator
|
|
def logcall(f): def wrapper(*a, **opts): print('calling ' + f.__name__) f(*a, **opts) print('called ' + f.__name__) return wrapper
@logcall def square(x): return x * x
square(5)
|
流程控制
|
if
|
if ( 0 == $n ) { print "no hits\n" } elsif ( 1 == $n ) { print "one hit\n" } else { print "$n hits\n" }
|
if 0 == n: print('no hits') elif 1 == n: print('one hit') else: print(str(n) + ' hits')
|
switch
|
use feature 'switch';
given ($n) { when (0) { print "no hits\n"; } when (1) { print "one hit\n"; } default { print "$n hits\n"; } }
|
none
|
while
|
while ( $i < 100 ) { $i++ }
|
while i < 100: i += 1
|
c-style for
|
for ( $i=0; $i <= 10; $i++ ) { print "$i\n"; }
|
none
|
Foreach
|
@a = (1..5);
foreach (@a) {
print "$_\n";
}
@a = (1..5);
for (@a) {
print "$_\n"
}
|
a = ['do', 're', 'mi', 'fa']
for i, s in enumerate(a):
print('%s at index %d' % (s, i))
for i in [1,2,3]:
print(i)
|
break, continue, redo
|
last next redo
|
break continue none
|
control structure keywords
|
do else elsif for foreach goto if unless until while
|
elif else for if while
|
what do does
|
executes following block and returns value of last statement executed
|
raises NameError unless a value was assigned to it
|
statement modifiers
|
print "positive\n" if $i > 0; print "nonzero\n" unless $i == 0;
|
none
|
raise exception
|
die "bad arg";
|
raise Exception('bad arg')
|
catch exception
|
eval { risky }; if ($@) { print "risky failed: $@\n"; }
|
try: risky() except: print('risky failed')
|
global variable for last exception
|
$EVAL_ERROR: $@ $OS_ERROR: $! $CHILD_ERROR: $?
|
last exception: sys.exc_info()[1]
|
define exception
|
none
|
class Bam(Exception): def __init__(self): super(Bam, self).__init__('bam!')
|
catch exception by type
|
none
|
try: raise Bam() except Bam as e: print(e)
|
finally/ensure
|
none
|
acquire_resource() try: risky() finally: release_resource()
|
start thread
|
use threads;
$func = sub { sleep 10 }; $thr = threads->new($func);
|
class sleep10(threading.Thread): def run(self): time.sleep(10)
thr = sleep10() thr.start()
|
wait on thread
|
$thr->join;
|
thr.join()
|
文件和输出
|
print to standard output
|
print "Hello, World!\n";
|
print('Hello, World!')
|
read from standard input
|
$line = <STDIN>;
|
line = sys.stdin.readline()
|
standard file handles
|
STDIN STDOUT STDERR
|
sys.stdin sys.stdout sys.stderr
|
open file
|
open my $f, "/etc/hosts"; or open FILE, "/etc/hosts";
|
f = open('/etc/hosts')
|
open file for writing
|
open my $f, ">/tmp/perl_test"; or open FILE, ">/tmp/perl_test";
|
f = open('/tmp/test', 'w')
|
open file for append
|
|
with open('/tmp/test') as f: f.write('lorem ipsum\n')
|
close file
|
close $f; or close FILE;
|
f.close()
|
read line
|
$line = <$f>; or $line = <FILE>;
|
f.readline()
|
iterate over file by line
|
while ($line = <$f>) {
|
for line in f:
|
chomp
|
chomp $line;
|
line = line.rstrip('\r\n')
|
read entire file into array or string
|
@a = <$f>; $s = do { local $/; <$f> };
|
a = f.readlines() s = f.read()
|
write to file
|
print $f "lorem ipsum";
|
f.write('lorem ipsum')
|
flush file handle
|
use IO::Handle;
$f->flush();
|
f.flush()
|
file test, regular file test
|
If (-e "/etc/hosts") {print exist;} -f "/etc/hosts"
|
os.path.exists('/etc/hosts') os.path.isfile('/etc/hosts')
|
copy file, remove file, rename file
|
use File::Copy;
copy("/tmp/foo", "/tmp/bar"); unlink "/tmp/foo"; move("/tmp/bar", "/tmp/foo"); unlink();
|
import shutil
shutil.copy('/tmp/foo', '/tmp/bar') os.remove('/tmp/foo') shutil.move('/tmp/bar', '/tmp/foo') os.remove()
|
set file permissions
|
chmod 0755, "/tmp/foo";
|
os.chmod('/tmp/foo', 0755)
|
temporary file
|
use File::Temp;
$f = File::Temp->new(); print $f "lorem ipsum\n"; close $f;
print "tmp file: "; print $f->filename . "\n";
|
import tempfile
f = tempfile.NamedTemporaryFile( prefix='foo') f.write('lorem ipsum\n') f.close()
print("tmp file: %s" % f.name)
|
in memory file
|
my ($f, $s); open($f, ">", \$s); print $f "lorem ipsum\n"; $s;
|
from StringIO import StringIO
f = StringIO() f.write('lorem ipsum\n') s = f.getvalue()
Python 3 moved StringIO to the io module
|
目录操作
|
build pathname
|
use File::Spec;
File::Spec->catfile("/etc", "hosts")
|
os.path.join('/etc', 'hosts')
|
dirname and basename
|
use File::Basename;
print dirname("/etc/hosts"); print basename("/etc/hosts");
|
os.path.dirname('/etc/hosts') os.path.basename('/etc/hosts')
|
absolute pathname
|
use Cwd;
Cwd::abs_path("..")
|
os.path.abspath('..')
|
iterate over directory by file
|
use File::Basename;
while ( </etc/*> ) { print basename($_) . "\n"; }
|
for filename in os.listdir('/etc'): print(filename)
|
make directory
|
use File::Path 'make_path';
make_path "/tmp/foo/bar";
|
dirname = '/tmp/foo/bar' if not os.path.isdir(dirname): os.makedirs(dirname)
|
recursive copy
|
# cpan -i File::Copy::Recursive use File::Copy::Recursive 'dircopy';
dircopy "/tmp/foodir", "/tmp/bardir";
|
import shutil
shutil.copytree('/tmp/foodir', '/tmp/bardir')
|
remove empty directory
|
rmdir "/tmp/foodir";
|
os.rmdir('/tmp/foodir')
|
remove directory and contents
|
use File::Path 'remove_tree';
remove_tree "/tmp/foodir";
|
import shutil
shutil.rmtree('/tmp/foodir')
|
directory test
|
-d "/tmp"
|
os.path.isdir('/tmp')
|
命令行操作
|
command line args, script name
|
scalar(@ARGV) $ARGV[0] $ARGV[1] etc $0
|
len(sys.argv)-1 sys.argv[1] sys.argv[2] etc sys.argv[0]
|
getopt
|
use Getopt::Long;
my ($src, $help);
sub usage { print "usage: $0 --f SRC\n"; exit -1; }
GetOptions("file=s" => \$src, "help" => \$help);
usage if $help;
|
import argparse
parser = argparse.ArgumentParser() parser.add_argument('--file', '-f', dest='file')
args = parser.parse_args() src = args.file
|
get and set environment variable
|
$ENV{"HOME"}
$ENV{"PATH") = "/bin";
|
os.getenv('HOME')
os.environ['PATH'] = '/bin'
|
exit
|
exit 0;
|
sys.exit(0)
|
set signal handller
|
$SIG{INT} = sub { die "exiting…\n"; };
|
import signal
def handler(signo, frame): print('exiting…') exit -1 signal.signal(signal.SIGINT, handler)
|
executable test
|
-x "/bin/ls"
|
os.access('/bin/ls', os.X_OK)
|
external command
|
system("ls -l /tmp") == 0 or die "ls failed";
|
if os.system('ls -l /tmp'): raise Exception('ls failed')
|
escaped external command
|
$path = <>; chomp($path); system("ls", "-l", $path) == 0 or die "ls failed";
|
import subprocess
cmd = ['ls', '-l', '/tmp'] if subprocess.call(cmd): raise Exception('ls failed')
|
backticks
|
my $files = `ls -l /tmp`; or my $files = qx(ls);
|
import subprocess
cmd = ['ls', '-l', '/tmp'] files = subprocess.check_output(cmd)
|
__________________________________________
|