比较perl+python的优点和缺点

时间:2022-09-01 17:35:28

 

perl (1987)

python (1991)

基础

模块导入

usestrict;

importos, 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);
subswap_globals{
($g1, $g2) = ($g2, $g1);
}

g1,g2 = 7, 8
defswap_globals():
globalg1, g2
g1, g2 = g2, g1

常量

useconstantPI => 3.14;

# uppercase identifiers
# constant by convention

PI = 3.14


undef

None

空测试

! defined $v

v ==None
v
isNone

访问未定义变量

error underuse strict; otherwise undef

raisesNameError

真假

1 ""

True False


undef0 0.0 "" "0"()

FalseNone 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

数学函数

useMath::Trigqw(
tan asin acos atan);

sqrt exp log sin costan asin acos atan atan2

frommath importsqrt, exp, log, \
sin, cos, tan, asin, acos, atan, atan2

四舍五入

# cpan -i Number::Format
useNumber::Format'round';
usePOSIXqw(ceil floor);

int($x)
round($x, 0)
ceil($x)
floor($x)
abs($x)

importmath

int(x)
int(round(x))
math.ceil(x)
math.floor(x)
abs(x)

最大最小

useList::Utilqw(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

raisesZeroDivisionError

大整数

converted to float; useMath::BigInt to create arbitrary length integers

becomes arbitrary length integer of typelong

大浮点数

inf

raisesOverflowError

随机数

int(rand() * 100)
rand()
none

importrandom

random.randint(0,99)
random.random()
random.gauss(0,1)

随机数

srand17;

my$sd = srand;
srand($sd);

importrandom

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 \c
x\e \f \n \r \t \xhh\x{hhhh} \oooPerl 5.14:\o{ooo}

single quoted:
\' \\

single and double quoted:
\
newline\\ \' \" \a \b \f \n \r \t \v \ooo\xhh

Python 3:
\u
hhhh\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
useText::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')
raiseValueError 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";
}

ifre.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::Pieceif use Time::Piece in effect, otherwise tm array

datetime.datetime

当前日期时间

useTime::Piece;

my$t= localtime(time);
my$utc= gmtime(time);

importdatetime

t = datetime.datetime.now()
utc = datetime.datetime.utcnow()

epoch转化

useTime::Local;
useTime::Piece;

my$epoch= timelocal($t);
my$t2= localtime(1304442000);

fromdatetime importdatetime asdt

epoch= int(t.strftime("%s"))
t2 = dt.fromtimestamp(1304442000)

当前epoch

$epoch =time;

importdatetime

t = datetime.datetime.now()
epoch= int(t.strftime("%s"))

strftime

useTime::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

useTime::Local;
useTime::Piece;

$s =
"2011-05-03 10:00:00";
$fmt =
"%Y-%m-%d %H:%M:%S";
$t = Time::Piece->strptime($s,$fmt);

fromdatetime importdatetime

s = '2011-05-03 10:00:00'
fmt = '%Y-%m-%d %H:%M:%S'
t = datetime.strptime(s, fmt)

解析日期

# cpan -i Date::Parse
useDate::Parse;

$epoch = str2time(
"July 7, 1999");

# pip install python-dateutil
importdateutil.parser

s = 'July 7, 1999'
t = dateutil.parser.parse(s)

时间差

Time::Secondsobject if use Time::Piece in effect; not meaningful to subtract tm arrays

datetime.timedeltaobject

时间运算

useTime::Seconds;

$now =
localtime(time);
$now += 10 * ONE_MINUTE() + 3;

importdatetime

delta= datetime.timedelta(
minutes=10,
seconds=3)
t = datetime.datetime.now() + delta

时区

Time::Piecehas local timezone if created withlocaltime and UTC timezone if created with gmtime;tm arrays have no timezone or offset info

adatetime object has no timezone information unless a tzinfoobject is provided when it is created

timezone name; offset from UTC; 是否夏令时

# cpan -i DateTime
useDateTime;
useDateTime::TimeZone;

$dt = DateTime->now();
$tz = DateTime::TimeZone->new(
name=>"local");

$tz->name;
$tz->offset_for_datetime($dt) /
3600;
$tz->is_dst_for_datetime($dt);

importtime

tm = time.localtime()

time.tzname[tm.tm_isdst]
(time.timezone / -3600) + tm.tm_isdst
tm.tm_isdst

microseconds

useTime::HiResqw(gettimeofday);

($sec, $usec) = gettimeofday;

t.microsecond

sleep

a float argument will be truncated to an integer:
sleep1;

importtime

time.sleep(0.5)

timeout

eval{
$SIG{ALRM}=sub{die"timeout!";};
alarm5;
sleep10;
};
alarm0;

importsignal, time

classTimeout(Exception):pass

deftimeout_handler(signo, fm):
raiseTimeout()

signal.signal(signal.SIGALRM,
timeout_handler)

try:
signal.alarm(5)
time.sleep(10)
exceptTimeout:
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

nota

使用

$a[0]

a[0]

更新

$a[0] ="lorem";

a[0] ='lorem'

越界访问

@a= ();
evaluates asundef:
$a[10];
increases array size to 11:
$a[10] ="lorem";

a= []
raisesIndexError:
a[10]
raisesIndexError:
a[10] =
'lorem'

index

useList::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 fori in range(0, 10)]

浅拷贝深拷贝

useStorable'dclone'

my@a = (1,2,[3,4]);
my$a2 = \@a;
my@a3 = @a;
my@a4 = @{dclone(\@a)};

importcopy

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" }

fori in[1,2,3]:
print(i)

遍历

none; use range iteration from0 to $#a and use index to look up value in the loop body

a= ['do','re','mi','fa']
fori, s inenumerate(a):
print('%s at index %d'% (s, i))

range

for$i (1..1_000_000) {
code
}

rangereplaces xrange in Python 3:
fori 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)cmplc($b) }@a;

a= ['b','A','a','B']
sorted(a)
a.sort()
a.sort(key=
str.lower)

去重复

useList::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(lambdax: x * x, [1,2,3])
# or use list comprehension:
[x*x for x in [1,2,3]]

filter

grep{ $_ > 1 } (1,2,3)

filter(lambdax: x > 1, [1,2,3])
# or use list comprehension:
[x for x in [1,2,3] if x > 1]

reduce

useList::Util'reduce';

reduce { $x + $y } 0, (1,2,3)

# import needed in Python 3 only
fromfunctools import reduce

reduce(lambdax, y: x+y, [1,2,3], 0)

All/any

# cpan -i List::MoreUtils
useList::MoreUtilsqw(all any);

all { $_ % 2 == 0 } (1,2,3,4)
any { $_ % 2 == 0 } (1,2,3,4)

all(i%2 == 0fori in[1,2,3,4])
any(i%2 == 0fori in[1,2,3,4])

shuffle and sample

useList::Util'shuffle';

@a = (1, 2, 3, 4);
shuffle(
@a);
none

fromrandom importshuffle, sample

a = [1, 2, 3, 4]
shuffle(a)
sample(a, 2)

zip

# cpan -i List::MoreUtils
useList::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 asundef:
$d{"lorem"};
adds key/value pair:
$d{"lorem"} = "ipsum";

d= {}
raisesKeyError:
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}
deld[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 fork, v
into_num.items()}

iteration

while( ($k, $v) = each%d ) {
code
}

fork, v ind.iteritems():
code

Python 3:
fork, v ind.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

fromcollections importdefaultdict

counts= defaultdict(lambda: 0)
counts[
'foo'] += 1

classFactorial(dict):
def__missing__(self, k):
ifk > 1:
returnk * self[k-1]
else:
return1

factorial= Factorial()

函数

函数申明

subadd { $_[0] +$_[1] }

subadd {
my($a,$b) =@_;
$a + $b;
}

defadd(a, b):
returna+b

函数调用

add(1, 2);

parens are optional:
add 1, 2;

add(1, 2)

参数丢失

set toundef

raisesTypeError

参数默认值

submy_log{
my$x = shift;
my$base = shift// 10;

log($x)/log($base);
}

my_log(42);
my_log(42,
exp(1));

importmath

defmy_log(x, base=10):
returnmath.log(x)/math.log(base)

my_log(42)
my_log(42, math.e)

变长参数

subfoo {
if( @_>= 1 ) {
print"first: $_[0]\n";
}
if( @_>= 2 ) {
print"last: $_[-1]\n";
}
}

deffoo(*a):
if len(a) >= 1:
print('first: '+ str(a[0]))
if len(a) >= 2:
print('last: '+ str(a[-1]))

命名参数

none

deffequal(x, y, **opts):
eps = opts.get('eps')or0.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

subfoo {
$_[0] += 1;
$_[1] .="ly";
}

my$n = 7;
my$s = "hard";
foo($n, $s);

not possible

pass array or dictionary by reference

subfoo {
$_[0][2] = 5;
$_[1]{"f"} = -1;
}

my@a = (1,2,3);
my%d = ("t"=> 1,"f"=> 0);
foo(\
@a, \%d);

deffoo(x, y):
x[2] = 5
y[
'f'] = -1

a = [1,2,3]
d = {'t':1,'f':0}
foo(a, d)

return value

returnarg or last expression evaluated

returnarg or None

multiple return values

subfirst_and_second{
return($_[0],$_[1]);
}
@a = (1,2,3);
($x, $y) = first_and_second(
@a);

deffirst_and_second(a):
returna[0], a[1]

x,y = first_and_second([1,2,3])

lambda declaration

$sqr =sub{ $_[0] *$_[0] }

body must be an expression:
sqr = lambdax: x * x

lambda invocation

$sqr->(2)

sqr(2)

function reference

my$func = \&add;

func= add

function with private state

usefeaturestate;

subcounter{
state $i = 0;
++$i;
}

printcounter() . "\n";

# state not private:
defcounter():
counter.i += 1
returncounter.i

counter.i = 0
print(counter())

closure

submake_counter{
my$i = 0;
returnsub { ++$i };
}
my$nays = make_counter;
print$nays->() . "\n";

# Python 3:
defmake_counter():
i = 0
defcounter():
nonlocal i
i += 1
returni
returncounter

nays = make_counter()

generator

none

defmake_counter():
i = 0
while True:
i += 1
yieldi

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"
}

if0 == n:
print('no hits')
elif1 == n:
print('one hit')
else:
print(str(n) + ' hits')

switch

usefeature'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++ }

whilei < 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 continuenone

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

raisesNameError 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";

raiseException('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

classBam(Exception):
def__init__(self):
super(Bam,self).__init__('bam!')

catch exception by type

none

try:
raiseBam()
exceptBam ase:
print(e)

finally/ensure

none

acquire_resource()
try:
risky()
finally:
release_resource()

start thread

usethreads;

$func =
sub{ sleep10 };
$thr = threads->new($func);

classsleep10(threading.Thread):
defrun(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

openmy $f, "/etc/hosts";or
openFILE, "/etc/hosts";

f= open('/etc/hosts')

open file for writing

openmy $f, ">/tmp/perl_test";or
openFILE, ">/tmp/perl_test";

f= open('/tmp/test','w')

open file for append

 

with open('/tmp/test')asf:
f.write(
'lorem ipsum\n')

close file

close$f; or
closeFILE;

f.close()

read line

$line = <$f>;or
$line = <FILE>;

f.readline()

iterate over file by line

while($line = <$f>) {

forline inf:

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

useIO::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

useFile::Copy;

copy(
"/tmp/foo","/tmp/bar");
unlink"/tmp/foo";
move(
"/tmp/bar","/tmp/foo");
unlink();

importshutil

shutil.copy(
'/tmp/foo','/tmp/bar')
os.remove(
'/tmp/foo')
shutil.move(
'/tmp/bar','/tmp/foo')
os.remove()

set file permissions

chmod0755, "/tmp/foo";

os.chmod('/tmp/foo', 0755)

temporary file

useFile::Temp;

$f = File::Temp->new();
print$f "lorem ipsum\n";
close $f;

print"tmp file: ";
print$f->filename . "\n";

importtempfile

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;

fromStringIO importStringIO

f = StringIO()
f.write(
'lorem ipsum\n')
s = f.getvalue()

Python 3 movedStringIO to the iomodule

目录操作

build pathname

useFile::Spec;

File::Spec->catfile(
"/etc","hosts")

os.path.join('/etc','hosts')

dirname and basename

useFile::Basename;

printdirname("/etc/hosts");
printbasename("/etc/hosts");

os.path.dirname('/etc/hosts')
os.path.basename(
'/etc/hosts')

absolute pathname

useCwd;

Cwd::abs_path(
"..")

os.path.abspath('..')

iterate over directory by file

useFile::Basename;

while( </etc/*>) {
printbasename($_) . "\n";
}

forfilename inos.listdir('/etc'):
print(filename)

make directory

useFile::Path'make_path';

make_path
"/tmp/foo/bar";

dirname= '/tmp/foo/bar'
if notos.path.isdir(dirname):
os.makedirs(dirname)

recursive copy

# cpan -i File::Copy::Recursive
useFile::Copy::Recursive'dircopy';

dircopy
"/tmp/foodir",
"/tmp/bardir";

importshutil

shutil.copytree(
'/tmp/foodir',
'/tmp/bardir')

remove empty directory

rmdir"/tmp/foodir";

os.rmdir('/tmp/foodir')

remove directory and contents

useFile::Path'remove_tree';

remove_tree
"/tmp/foodir";

importshutil

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

useGetopt::Long;

my($src,$help);

subusage{
print"usage: $0 --f SRC\n";
exit-1;
}

GetOptions(
"file=s"=> \$src,
"help"=> \$help);

usage
if$help;

importargparse

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

exit0;

sys.exit(0)

set signal handller

$SIG{INT} =sub{
die"exiting…\n";
};

importsignal

defhandler(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";

ifos.system('ls -l /tmp'):
raiseException('ls failed')

escaped external command

$path = <>;
chomp($path);
system("ls","-l", $path) == 0or
die"ls failed";

importsubprocess

cmd = ['ls','-l','/tmp']
ifsubprocess.call(cmd):
raiseException('ls failed')

backticks

my$files = `ls -l /tmp`;or
my$files = qx(ls);

importsubprocess

cmd = ['ls','-l','/tmp']
files= subprocess.check_output(cmd)

__________________________________________