为什么使用python?
易学,可以完成复杂的任务。Bash,perl,python的简单比较:
# cat loop.sh
#!/bin/bash
for a in 1 2; do
for b in a b; do
echo "$a $b"
done
done
# cat loop.pl
#!/usr/bin/env perl
foreach $a ('1', '2') {
foreach $b ('a', 'b') {
print "$a $b\n";
}
}
# cat loop.py
#!/usr/bin/env python
for a in [1, 2]:
for b in ['a', 'b']:
print a, b
判断一个目录是否存在:
# cat isdir.sh
#!/bin/bash
if [ -d "/tmp" ] ; then
echo "/tmp is a directory"
else
echo "/tmp is not a directory"
fi
# cat isdir.pl
#!/usr/bin/env perl
if (-d "/tmp") {
print "/tmp is a directory\n";
}
else {
print "/tmp is not a directory\n";
}
# cat isdir.py
#!/usr/bin/env python
import os
if os.path.isdir("/tmp"):
print "/tmp is a directory"
else:
print "/tmp is not a directory"
python简单支持OOP。
Perl中有这么一个类:
package Server;
use strict;
sub new {
my $class = shift;
my $self = {};
$self->{IP} = shift;
$self->{HOSTNAME} = shift;
bless($self);
return $self;
}
sub set_ip {
my $self = shift;
$self->{IP} = shift;
return $self->{IP};
}
sub set_hostname {
my $self = shift;
$self->{HOSTNAME} = shift;
return $self->{HOSTNAME};
}
sub ping {
my $self = shift;
my $external_ip = shift;
my $self_ip = $self->{IP};
my $self_host = $self->{HOSTNAME};
print "Pinging $external_ip from $self_ip ($self_host)\n";
return 0;
}
1;
# cat oo.pl
#!/usr/bin/env perl
use Server;
$server = Server->new('192.168.1.15', 'grumbly');
$server->ping('192.168.1.20');
Python的实现:
# cat oo.pl
#!/usr/bin/env perl
use Server;
$server = Server->new('192.168.1.15', 'grumbly');
$server->ping('192.168.1.20');
[root@server code]# cat oo.py
#!/usr/bin/env python
class Server(object):
def __init__(self, ip, hostname):
self.ip = ip
self.hostname = hostname
def set_ip(self, ip):
self.ip = ip
def set_hostname(self, hostname):
self.hostname = hostname
def ping(self, ip_addr):
print "Pinging %s from %s (%s)" % (ip_addr, self.ip, self.hostname)
if __name__ == '__main__':
server = Server('192.168.1.20', 'bumbly')
server.ping('192.168.1.15')
有丰富的包,参见PyPI ()
在python的shell输入import this,可以查看到python的设计原则。
§1.2 动机(略)
§1.3 基础
下载ipython :。
# ipython
/usr/local/lib/python2.6/site-packages/IPython/Magic.py:38: DeprecationWarning: the sets module is deprecated
from sets import Set
Python 2.6.2 (r262:71600, Apr 29 2009, 14:54:06)
Type "copyright", "credits" or "license" for more information.
IPython 0.9.1 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object'. ?object also works, ?? prints more.
In [1]: print "I can program in Python"
------> print("I can program in Python")
I can program in Python
In [2]:
§1.4 语句执行
>>> import subprocess
>>> subprocess.call(["ls","-l","/tmp/"])
subprocess.call(["some_command", "some_argument", "another_argument_or_path"])
写成python脚本:
# cat pyls.py
#!/usr/bin/env python
#Python wrapper for the ls command
import subprocess
subprocess.call(["ls","-l"])
# cat pysysinfo.py
#!/usr/bin/env python
#A System Information Gathering Script
import subprocess
#Command 1
uname = "uname"
uname_arg = "-a"
print "Gathering system information with %s command:\n" % uname
subprocess.call([uname, uname_arg])
#Command 2
diskspace = "df"
diskspace_arg = "-h"
print "Gathering diskspace information %s command:\n" % diskspace
subprocess.call([diskspace, diskspace_arg])
# cat bashsysinfo.sh
#!/usr/bin/env bash
#A System Information Gathering Script
#Command 1
UNAME="uname -a"
printf "Gathering system information with the $UNAME command: \n\n"
$UNAME
#Command 2
DISKSPACE="df -h"
printf "Gathering diskspace information with the $DISKSPACE command: \n\n"
$DISKSPACE
更快捷的方式:subprocess.call("df -h", shell=True)
查看一个模块的内容,先导入,import subprocess。输入“subprocess.”,按TAB。更多帮助:subprocess.call?,这个标准的python是没有的。
§1.5 函数
In [10]: def pyfunc():
....: print "Hello function"
....:
....:
In [11]: pyfunc
Out[11]: 2a9a74e140>
In [12]: pyfunc()
Hello function
In [13]: for i in range(5):
....: pyfunc()
....:
....:
Hello function
Hello function
Hello function
Hello function
Hello function
In [14]:
注意python的冒号和缩进。Bash的对比:
bash-3.2$ function shfunc()
> {
> printf "Hello function\n"
> }
bash-3.2$ for (( i=0 ; i < 5 ; i++))
> do
> shfunc
> done
Hello function
Hello function
Hello function
Hello function
Hello function
# cat pysysinfo_func.py
#!/usr/bin/env python
#System Information Gathering Script
import subprocess
#Command 1
def uname_func():
uname = "uname"
uname_arg = "-a"
print "Gathering system information with %s command:\n" % uname
subprocess.call([uname, uname_arg])
#Command 2
def disk_func():
diskspace = "df"
diskspace_arg = "-h"
print "Gathering diskspace information %s command:\n" % diskspace
subprocess.call([diskspace, diskspace_arg])
#Main function that call other functions
def main():
uname_func()
disk_func()
main()
bash的实现:
# cat bashsysinfo_func.sh
#!/usr/bin/env bash
#A System Information Gathering Script
#Command 1
function uname_func ()
{
UNAME="uname -a"
printf "Gathering system information with the $UNAME command: \n\n"
$UNAME
}
#Command 2
function disk_func ()
{
DISKSPACE="df -h"
printf "Gathering diskspace information with the $DISKSPACE command: \n\n"
$DISKSPACE
}
function main ()
{
uname_func
disk_func
}
Main
§1.6 重用
.py的文件都可以作为模块导入。以下方式控制主函数的执行。
#Main function that call other functions
def main():
uname_func()
disk_func()
if __name__ == "__main__":
main()
# cat new_pysysinfo.py
#Very short script that reuses pysysinfo_func_2 code
from pysysinfo_func_2 import disk_func
import subprocess
def tmp_space():
tmp_usage = "du"
tmp_arg = "-h"
path = "/tmp"
print "Space used in /tmp directory"
subprocess.call([tmp_usage, tmp_arg, path])
def main():
disk_func()
tmp_space()
if __name__ == "__main__":
main()