Python之所以应用越来越广泛,在一定程度上也依赖于其为程序员提供了大量的模块以供使用,如果想要使用模块,则需要导入。导入模块有一下几种方法:
1
2
3
4
|
import
module
from
module.xx.xx
import
xx
from
module.xx.xx
import
xx as rename
from
module.xx.xx
import
*
|
导入模块其实就是告诉Python解释器去解释那个py文件
导入一个py文件,解释器解释该py文件
导入一个包,解释器解释该包下的 __init__.py 文件
那么问题来了,导入模块时是根据那个路径作为基准来进行的呢?即:sys.path
1
2
3
|
>>>
import
sys
>>>
print
sys.path
['
', '
C:\\WINDOWS\\SYSTEM32\\python27.
zip
', '
d:\\Python27\\DLLs
', '
d:\\Python27\\lib
', '
d:\\Python27\\lib\\plat
-
win
', '
d:\\Python27\\lib\\lib
-
tk
', '
d:\\Python27
', '
d:\\Python27\\lib\\site
-
packages']
|
如果sys.path路径列表没有你想要的路径,可以通过 sys.path.append('路径') 添加。
通过os模块可以获取各种目录,例如:
1
2
3
4
|
import
sys
import
os
pre_path
=
os.path.abspath(
'../'
)
sys.path.append(pre_path)
|
开源模块
下载安装有两种方式:
1
2
3
4
|
yum
pip
apt-get
...
|
1
2
3
4
5
|
下载源码
解压源码
进入目录
编译源码 python setup.py build
安装源码 python setup.py
install
|
注:在使用源码安装时,需要使用到gcc编译和python开发环境,所以,需要先执行:
1
2
3
4
|
yum
install
gcc
yum
install
python-devel
或
apt-get python-dev
|
安装成功后,模块会自动安装到 sys.path 中的某个目录中,如:
/usr/lib/python2.7/site-packages/
二、导入模块
同自定义模块中导入的方式
三、模块 paramiko
paramiko是一个用于做远程控制的模块,使用该模块可以对远程服务器进行命令或文件操作,值得一说的是,fabric和ansible内部的远程管理就是使用的paramiko来现实。
1、下载安装
# pycrypto,由于 paramiko 模块内部依赖pycrypto,所以先下载安装pycrypto
# 下载安装 pycrypto
1
2
3
4
5
|
wget https:
//ftp
.dlitz.net
/pub/dlitz/crypto/pycrypto/pycrypto-2
.6.1.
tar
.gz
tar
-xvf pycrypto-2.6.1.
tar
.gz
cd
pycrypto-2.6.1
python setup.py build
python setup.py
install
|
# 进入python环境,导入Crypto检查是否安装成功
# 下载安装 paramiko
1
2
3
4
5
|
wget http:
//pkgs
.fedoraproject.org
/repo/pkgs/python-paramiko/paramiko-1
.10.1.
tar
.gz
/4ba105e2d8535496fd633889396b20b7/paramiko-1
.10.1.
tar
.gz
tar
-xvf paramiko-1.10.1.
tar
.gz
cd
paramiko-1.10.1
python setup.py build
python setup.py
install
|
# 进入python环境,导入paramiko检查是否安装成功
2、使用模块
1
2
3
4
5
6
7
8
9
|
#!/usr/bin/env python
#coding:utf-8
import
paramiko
ssh
=
paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(
'192.168.1.108'
,
22
,
'alex'
,
'123'
)
stdin, stdout, stderr
=
ssh.exec_command(
'df'
)
print
stdout.read()
ssh.close();
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
通过秘钥登录之前要先将本地机器上账户www(这里用www为例)生成公钥,然后将公钥传到要操作的服务器上:
[www@Python ~]$
ssh
-keygen
Generating public
/private
rsa key pair.
Enter
file
in
which
to save the key (
/home/www/
.
ssh
/id_rsa
):
Created directory
'/home/www/.ssh'
.
Enter passphrase (empty
for
no passphrase):
Enter same passphrase again:
Your identification has been saved
in
/home/www/
.
ssh
/id_rsa
.
Your public key has been saved
in
/home/www/
.
ssh
/id_rsa
.pub.
The key fingerprint is:
1e:ef:cf:cb:0d:91:c2:03:4c:ed:3d:f1:ab:05:55:e6 www@Python
The key's randomart image is:
+--[ RSA 2048]----+
| .. .o|
| o . . .o |
| o. . + E|
| o. +.. |
| S + oo . |
| . o o .o |
| . . .o |
| . o.o |
| ..=.. |
+-----------------+
将生成的公钥id_rsa.pub传到目标主机上,这里的目标主机为192.168.0.203
[www@Python ~]$
cd
.
ssh
/
[www@Python .
ssh
]$
ssh
-copy-
id
-i id_rsa.pub 192.168.0.203
www@192.168.0.203's password:
Now try logging into the machine, with
"ssh '192.168.0.203'"
, and check
in
:
.
ssh
/authorized_keys
to
make
sure we haven
't added extra keys that you weren'
t expecting.
import
paramiko
private_key_path =
'/home/auto/.ssh/id_rsa'
key = paramiko.RSAKey.from_private_key_file(private_key_path)
ssh
= paramiko.SSHClient()
ssh
.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh
.connect(
'主机名 '
, 端口,
'用户名'
, key)
stdin, stdout, stderr =
ssh
.exec_command(
'df'
)
print stdout.
read
()
ssh
.close()
|
执行命令 - 通过密钥链接服务器
1
2
3
4
5
6
7
|
import
os,sys
import
paramiko
t
=
paramiko.Transport((
'182.92.219.86'
,
22
))
t.connect(username
=
'ryan'
,password
=
'123'
)
sftp
=
paramiko.SFTPClient.from_transport(t)
sftp.put(
'/tmp/test.py'
,
'/tmp/test.py'
)
t.close()
|
1
2
3
4
5
6
7
|
import
os,sys
import
paramiko
t
=
paramiko.Transport((
'182.92.219.86'
,
22
))
t.connect(username
=
'ryan'
,password
=
'123'
)
sftp
=
paramiko.SFTPClient.from_transport(t)
sftp.get(
'/tmp/test.py'
,
'/tmp/test2.py'
)
t.close()
|
通过秘钥等于远程主机然后查看进程占用资源:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
#!/usr/bin/env python
#coding:utf-8
import
paramiko
host_lists
=
(
(
'server203'
,
'192.168.0.203'
),
(
'server214'
,
'192.168.0.214'
),
(
'server234'
,
'192.168.0.234'
),
(
'server235'
,
'192.168.0.235'
),
)
def
getServerInfo(host,user,keys,services):
conn
=
paramiko.SSHClient()
conn.load_system_host_keys()
conn.set_missing_host_key_policy(paramiko.AutoAddPolicy())
conn.connect(host,
22
,user,keys)
stdin,stdout,stderr
=
conn.exec_command(
"ps aux|awk '{print $3,$4,$5,$6,$11}'|grep %s"
%
services)
info
=
stdout.read()
conn.close()
return
info
if
__name__
=
=
'__main__'
:
print
"hostname %CPU %MEM VSZ RSS services"
for
host
in
host_lists:
info
=
getServerInfo(host[
1
],
'www'
,
'pkey=key'
,
'rsyslogd'
)
info_list
=
info.split()
print
"%s %s %s %s %s %s "
%
(host[
0
],info_list[
0
],info_list[
1
],info_list[
2
],info_list[
3
],info_list[
4
] )
|
上传或者下载文件 - 通过用户名和密码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import
os,sys
import
paramiko
t
=
paramiko.Transport((
'182.92.219.86'
,
22
))
t.connect(username
=
'wupeiqi'
,password
=
'123'
)
sftp
=
paramiko.SFTPClient.from_transport(t)
sftp.put(
'/tmp/test.py'
,
'/tmp/test.py'
)
t.close()
import
os,sys
import
paramiko
t
=
paramiko.Transport((
'182.92.219.86'
,
22
))
t.connect(username
=
'wupeiqi'
,password
=
'123'
)
sftp
=
paramiko.SFTPClient.from_transport(t)
sftp.get(
'/tmp/test.py'
,
'/tmp/test2.py'
)
t.close()
|
上传或下载文件 - 通过密钥
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import
paramiko
pravie_key_path
=
'/home/auto/.ssh/id_rsa'
key
=
paramiko.RSAKey.from_private_key_file(pravie_key_path)
t
=
paramiko.Transport((
'182.92.219.86'
,
22
))
t.connect(username
=
'wupeiqi'
,pkey
=
key)
sftp
=
paramiko.SFTPClient.from_transport(t)
sftp.put(
'/tmp/test3.py'
,
'/tmp/test3.py'
)
t.close()
import
paramiko
pravie_key_path
=
'/home/auto/.ssh/id_rsa'
key
=
paramiko.RSAKey.from_private_key_file(pravie_key_path)
t
=
paramiko.Transport((
'182.92.219.86'
,
22
))
t.connect(username
=
'wupeiqi'
,pkey
=
key)
sftp
=
paramiko.SFTPClient.from_transport(t)
sftp.get(
'/tmp/test3.py'
,
'/tmp/test4.py'
)
t.close()
|
内置模块
一、os
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
用于提供系统级别的操作
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径
os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd
os.curdir 返回当前目录: ('.')
os.pardir 获取当前目录的父目录字符串名:('..')
os.makedirs('dirname1/dirname2') 可生成多层递归目录
os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname
os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname
os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印
os.remove() 删除一个文件
os.rename("oldname","newname") 重命名文件/目录
os.stat('path/filename') 获取文件/目录信息
os.sep 输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/"
os.linesep 输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
os.pathsep 输出用于分割文件路径的字符串
os.name 输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
os.system("bash command") 运行shell命令,直接显示
os.environ 获取系统环境变量
os.path.abspath(path) 返回path规范化的绝对路径
os.path.split(path) 将path分割成目录和文件名二元组返回
os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素
os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素
os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False
os.path.isabs(path) 如果path是绝对路径,返回True
os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False
os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False
os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略
os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间
os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
|
二、sys
用于提供对解释器相关的操作
1
2
3
4
5
6
7
8
|
sys.argv 命令行参数List,第一个元素是程序本身路径
sys.exit(n) 退出程序,正常退出时exit(0)
sys.version 获取Python解释程序的版本信息
sys.maxint 最大的Int值
sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform 返回操作系统平台名称
sys.stdout.write('please:')
val = sys.stdin.readline()[:-1]
|
三、hashlib
用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import
hashlib
# ######## md5 ########
hash
=
hashlib.md5()
hash
.update(
'admin'
)
print
hash
.hexdigest()
# ######## sha1 ########
hash
=
hashlib.sha1()
hash
.update(
'admin'
)
print
hash
.hexdigest()
# ######## sha256 ########
hash
=
hashlib.sha256()
hash
.update(
'admin'
)
print
hash
.hexdigest()
# ######## sha384 ########
hash
=
hashlib.sha384()
hash
.update(
'admin'
)
print
hash
.hexdigest()
# ######## sha512 ########
hash
=
hashlib.sha512()
hash
.update(
'admin'
)
print
hash
.hexdigest()
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
import
hashlib
# ######## md5 ########
hash
=
hashlib.md5(
'898oaFs09f'
)
hash
.update(
'admin'
)
print
hash
.hexdigest()
还不够吊?python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 再进行处理然后再加密
1
2
3
4
5
|
import
hmac
h
=
hmac.new(
'wueiqi'
)
h.update(
'hellowo'
)
print
h.hexdigest()
不能再牛逼了!!!
|
四、json 和 pickle
用于序列化的两个模块
json,用于字符串 和 python数据类型间进行转换
pickle,用于python特有的类型 和 python的数据类型间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
1
2
|
>>>
import
pickle
>>> data
=
{
'k1'
:
123
,
'k2'
:
'Hello'
}
|
#pickle.dumps将数据通过特殊的形式转换为只有python语言人事id字符串
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> p_str
=
pickle.dumps(data)
>>>
print
p_str
(dp0
S
'k2'
p1
S
'Hello'
p2
sS
'k1'
p3
I123
s.
>>>
|
#pickle.dump将数据通过特殊的形式转换为只有Python语言认识的字符串,并写入文件
1
2
3
|
>>> with
open
(
'/server/scripts/day005/result.pk'
,
'w'
) as fp:
... pickle.dump(data,fp)
...
|
import json
#json.dumps 将数据通过特殊的形式转换为所有程序语言都认识的字符串
1
2
3
4
5
|
>>>
import
json
>>> j_str
=
json.dumps(data)
>>>
print
j_str
{
"k2"
:
"Hello"
,
"k1"
:
123
}
>>>
|
#json.dump将数据通过特殊的形式转换为所有程序语言都能认识的字符串,并写入文件
1
2
3
4
|
>>> with
open
(
'/server/scripts/day005/result.json'
,
'w'
) as fp:
... json.dump(data,fp)
...
>>>
|
注释:
①对于pickle和json他们的各自的四个方法dumps、dump、loads、load;dumps和loads是在内存里处理数据,即处理之后的数据还是在内存;而dump和load处理(换句话说就是序列化操作)后的数据存放到硬盘,即:dump将内存中的数据写入硬盘,load是将硬盘读出来(到内存)
②json不能序列化日期、类、生成器等数据;而pickle则可以序列化目前所有数据,至少目前没有出现不可以被pickle序列化数据。
五、执行系统命令
可以执行shell命令的相关模块和函数有:
os.system
os.spawn*
os.popen* --废弃
popen2.* --废弃
commands.* --废弃,3.x中被移除
import commands result = commands.getoutput('cmd') result = commands.getstatus('cmd') result = commands.getstatusoutput('cmd'
以上执行shell命令的相关的模块和函数的功能均在 subprocess 模块中实现,并提供了更丰富的功能。
call
执行命令,返回状态码
执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
1
2
|
ret
=
subprocess.check_call([
"ls"
,
"-l"
])
ret
=
subprocess.check_call(
"exit 1"
, shell
=
True
)
|
shell = True ,允许 shell 命令是字符串形式,换句话说将参数传递给shell,交给shell去执行
如果subprocess.check_output执行shell命令通过Python的方式,那么必须给subprocess.check_output传递一个列表,否则会报错:
1
2
3
|
>>> subprocess.check_output([
"df"
,
"-Th"
])
'Filesystem Type Size Used Avail Use% Mounted on\n/dev/sda2 ext4 39G 2.3G 34G 7% /\ntmpfs tmpfs 175M 0 175M 0% /dev/shm\n/dev/sda1 ext4 194M 32M 153M 18% /boot\n'
>>>
|
1
2
3
4
5
6
7
8
9
10
11
|
>>> subprocess.check_output(
"df -Th"
)
Traceback (most recent call last):
File
"<stdin>"
, line
1
,
in
<module>
File
"/usr/local/lib/python2.7/subprocess.py"
, line
566
,
in
check_output
process
=
Popen(stdout
=
PIPE,
*
popenargs,
*
*
kwargs)
File
"/usr/local/lib/python2.7/subprocess.py"
, line
710
,
in
__init__
errread, errwrite)
File
"/usr/local/lib/python2.7/subprocess.py"
, line
1335
,
in
_execute_child
raise
child_exception
OSError: [Errno
2
] No such
file
or
directory
>>>
|
以shell的方式执行系统命令:
1
2
3
|
>>> subprocess.check_output(
"df -Th"
,shell
=
True
)
'Filesystem Type Size Used Avail Use% Mounted on\n/dev/sda2 ext4 39G 2.3G 34G 7% /\ntmpfs tmpfs 175M 0 175M 0% /dev/shm\n/dev/sda1 ext4 194M 32M 153M 18% /boot\n'
>>>
|
check_call
执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
1
2
3
|
subprocess.check_output([
"echo"
,
"Hello World!"
])
subprocess.check_output(
"exit 1"
, shell
=
True
)
subprocess.Popen(...)
|
check_output
执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
1
2
|
subprocess.check_output([
"echo"
,
"Hello World!"
])
subprocess.check_output(
"exit 1"
, shell
=
True
)
|
subprocess.Popen(...)
用于执行复杂的系统命令
参数:
args:shell命令,可以是字符串或者序列类型(如:list,元组)
bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。
shell:同上
cwd:用于设置子进程的当前目录
env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
startupinfo与createionflags只在windows下有效
将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
1
2
3
|
import
subprocess
ret1
=
subprocess.Popen([
"mkdir"
,
"t1"
])
ret2
=
subprocess.Popen(
"mkdir t2"
, shell
=
True
)
|
终端输入的命令分为两种:
输入即可得到输出,如:ifconfig
输入进行某环境,依赖再输入,如:python
1
2
|
import
subprocess
obj
=
subprocess.Popen(
"mkdir t3"
, shell
=
True
, cwd
=
'/home/dev'
,)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
subprocess
obj
=
subprocess.Popen([
"python"
], stdin
=
subprocess.PIPE, stdout
=
subprocess.PIPE, stderr
=
subprocess.PIPE)
obj.stdin.write(
'print 1 \n '
)
obj.stdin.write(
'print 2 \n '
)
obj.stdin.write(
'print 3 \n '
)
obj.stdin.write(
'print 4 \n '
)
obj.stdin.close()
cmd_out
=
obj.stdout.read()
obj.stdout.close()
cmd_error
=
obj.stderr.read()
obj.stderr.close()
print
cmd_out
print
cmd_error
|
1
2
3
4
5
6
7
8
|
import
subprocess
obj
=
subprocess.Popen([
"python"
], stdin
=
subprocess.PIPE, stdout
=
subprocess.PIPE, stderr
=
subprocess.PIPE)
obj.stdin.write(
'print 1 \n '
)
obj.stdin.write(
'print 2 \n '
)
obj.stdin.write(
'print 3 \n '
)
obj.stdin.write(
'print 4 \n '
)
out_error_list
=
obj.communicate()
print
out_error_list
|
1
2
3
4
|
import
subprocess
obj
=
subprocess.Popen([
"python"
], stdin
=
subprocess.PIPE, stdout
=
subprocess.PIPE, stderr
=
subprocess.PIPE)
out_error_list
=
obj.communicate(
'print "hello"'
)
print
out_error_list
|
六、shutil
高级的 文件、文件夹、压缩包 处理模块
shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另一个文件中,可以部分内容
1
2
3
4
5
6
7
|
def
copyfileobj(fsrc, fdst, length
=
16
*
1024
):
"""copy data from file-like object fsrc to file-like object fdst"""
while
1
:
buf
=
fsrc.read(length)
if
not
buf:
break
fdst.write(buf)
|
shutil.copyfile(src, dst)
拷贝文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
def
copyfile(src, dst):
"""Copy data from src to dst"""
if
_samefile(src, dst):
raise
Error(
"`%s` and `%s` are the same file"
%
(src, dst))
for
fn
in
[src, dst]:
try
:
st
=
os.stat(fn)
except
OSError:
# File most likely does not exist
pass
else
:
# XXX What about other special files? (sockets, devices...)
if
stat.S_ISFIFO(st.st_mode):
raise
SpecialFileError(
"`%s` is a named pipe"
%
fn)
with
open
(src,
'rb'
) as fsrc:
with
open
(dst,
'wb'
) as fdst:
copyfileobj(fsrc, fdst)
|
shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变
1
2
3
4
5
6
|
def
copymode(src, dst):
"""Copy mode bits from src to dst"""
if
hasattr
(os,
'chmod'
):
st
=
os.stat(src)
mode
=
stat.S_IMODE(st.st_mode)
os.chmod(dst, mode)
|
shutil.copystat(src, dst)
拷贝状态的信息,包括:mode bits, atime, mtime, flags
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
def
copystat(src, dst):
"""Copy all stat info (mode bits, atime, mtime, flags) from src to dst"""
st
=
os.stat(src)
mode
=
stat.S_IMODE(st.st_mode)
if
hasattr
(os,
'utime'
):
os.utime(dst, (st.st_atime, st.st_mtime))
if
hasattr
(os,
'chmod'
):
os.chmod(dst, mode)
if
hasattr
(os,
'chflags'
)
and
hasattr
(st,
'st_flags'
):
try
:
os.chflags(dst, st.st_flags)
except
OSError, why:
for
err
in
'EOPNOTSUPP'
,
'ENOTSUP'
:
if
hasattr
(errno, err)
and
why.errno
=
=
getattr
(errno, err):
break
else
:
raise
|
shutil.copy(src, dst)
拷贝文件和权限
1
2
3
4
5
6
7
8
|
def
copy(src, dst):
"""Copy data and mode bits ("cp src dst").
The destination may be a directory.
"""
if
os.path.isdir(dst):
dst
=
os.path.join(dst, os.path.basename(src))
copyfile(src, dst)
copymode(src, dst)
|
shutil.copy2(src, dst)
拷贝文件和状态信息
1
2
3
4
5
6
7
8
|
def
copy2(src, dst):
"""Copy data and all stat info ("cp -p src dst").
The destination may be a directory.
"""
if
os.path.isdir(dst):
dst
=
os.path.join(dst, os.path.basename(src))
copyfile(src, dst)
copystat(src, dst)
|
shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件
例如:copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
def
ignore_patterns(
*
patterns):
"""Function that can be used as copytree() ignore parameter.
Patterns is a sequence of glob-style patterns
that are used to exclude files"""
def
_ignore_patterns(path, names):
ignored_names
=
[]
for
pattern
in
patterns:
ignored_names.extend(fnmatch.
filter
(names, pattern))
return
set
(ignored_names)
return
_ignore_patterns
def
copytree(src, dst, symlinks
=
False
, ignore
=
None
):
"""Recursively copy a directory tree using copy2().
The destination directory must not already exist.
If exception(s) occur, an Error is raised with a list of reasons.
If the optional symlinks flag is true, symbolic links in the
source tree result in symbolic links in the destination tree; if
it is false, the contents of the files pointed to by symbolic
links are copied.
The optional ignore argument is a callable. If given, it
is called with the `src` parameter, which is the directory
being visited by copytree(), and `names` which is the list of
`src` contents, as returned by os.listdir():
callable(src, names) -> ignored_names
Since copytree() is called recursively, the callable will be
called once for each directory that is copied. It returns a
list of names relative to the `src` directory that should
not be copied.
XXX Consider this example code rather than the ultimate tool.
"""
names
=
os.listdir(src)
if
ignore
is
not
None
:
ignored_names
=
ignore(src, names)
else
:
ignored_names
=
set
()
os.makedirs(dst)
errors
=
[]
for
name
in
names:
if
name
in
ignored_names:
continue
srcname
=
os.path.join(src, name)
dstname
=
os.path.join(dst, name)
try
:
if
symlinks
and
os.path.islink(srcname):
linkto
=
os.readlink(srcname)
os.symlink(linkto, dstname)
elif
os.path.isdir(srcname):
copytree(srcname, dstname, symlinks, ignore)
else
:
# Will raise a SpecialFileError for unsupported file types
copy2(srcname, dstname)
# catch the Error from the recursive copytree so that we can
# continue with other files
except
Error, err:
errors.extend(err.args[
0
])
except
EnvironmentError, why:
errors.append((srcname, dstname,
str
(why)))
try
:
copystat(src, dst)
except
OSError, why:
if
WindowsError
is
not
None
and
isinstance
(why, WindowsError):
# Copying file access times may fail on Windows
pass
else
:
errors.append((src, dst,
str
(why)))
if
errors:
raise
Error, errors
|
shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
def
rmtree(path, ignore_errors
=
False
, onerror
=
None
):
"""Recursively delete a directory tree.
If ignore_errors is set, errors are ignored; otherwise, if onerror
is set, it is called to handle the error with arguments (func,
path, exc_info) where func is os.listdir, os.remove, or os.rmdir;
path is the argument to that function that caused it to fail; and
exc_info is a tuple returned by sys.exc_info(). If ignore_errors
is false and onerror is None, an exception is raised.
"""
if
ignore_errors:
def
onerror(
*
args):
pass
elif
onerror
is
None
:
def
onerror(
*
args):
raise
try
:
if
os.path.islink(path):
# symlinks to directories are forbidden, see bug #1669
raise
OSError(
"Cannot call rmtree on a symbolic link"
)
except
OSError:
onerror(os.path.islink, path, sys.exc_info())
# can't continue even if onerror hook returns
return
names
=
[]
try
:
names
=
os.listdir(path)
except
os.error, err:
onerror(os.listdir, path, sys.exc_info())
for
name
in
names:
fullname
=
os.path.join(path, name)
try
:
mode
=
os.lstat(fullname).st_mode
except
os.error:
mode
=
0
if
stat.S_ISDIR(mode):
rmtree(fullname, ignore_errors, onerror)
else
:
try
:
os.remove(fullname)
except
os.error, err:
onerror(os.remove, fullname, sys.exc_info())
try
:
os.rmdir(path)
except
os.error:
onerror(os.rmdir, path, sys.exc_info())
|
shutil.move(src, dst)
递归的去移动文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
def
move(src, dst):
"""Recursively move a file or directory to another location. This is
similar to the Unix "mv" command.
If the destination is a directory or a symlink to a directory, the source
is moved inside the directory. The destination path must not already
exist.
If the destination already exists but is not a directory, it may be
overwritten depending on os.rename() semantics.
If the destination is on our current filesystem, then rename() is used.
Otherwise, src is copied to the destination and then removed.
A lot more could be done here... A look at a mv.c shows a lot of
the issues this implementation glosses over.
"""
real_dst
=
dst
if
os.path.isdir(dst):
if
_samefile(src, dst):
# We might be on a case insensitive filesystem,
# perform the rename anyway.
os.rename(src, dst)
return
real_dst
=
os.path.join(dst, _basename(src))
if
os.path.exists(real_dst):
raise
Error,
"Destination path '%s' already exists"
%
real_dst
try
:
os.rename(src, real_dst)
except
OSError:
if
os.path.isdir(src):
if
_destinsrc(src, dst):
raise
Error,
"Cannot move a directory '%s' into itself '%s'."
%
(src, dst)
copytree(src, real_dst, symlinks
=
True
)
rmtree(src)
else
:
copy2(src, real_dst)
os.unlink(src)
|
shutil.make_archive(base_name, format,...)
创建压缩包并返回文件路径,例如:zip、tar
base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如:www =>保存至当前路径
如:/Users/ryan/www =>保存至/Users/ryan/
format:压缩包种类,“zip”, “tar”, “bztar”,“gztar”
root_dir:要压缩的文件夹路径(默认当前目录)
owner:用户,默认当前用户
group:组,默认当前组
logger:用于记录日志,通常是logging.Logger对象
#将 /Users/ryan/Downloads/test 下的文件打包放置当前程序目录
1
2
|
import
shutil
ret
=
shutil.make_archive(
"wwwwwwwwww"
,
'gztar'
, root_dir
=
'/Users/ryan/Downloads/test'
)
|
#将 /Users/ryan/Downloads/test 下的文件打包放置 /Users/ryan/目录
1
2
|
import
shutil
ret
=
shutil.make_archive(
"/Users/ryan/wwwwwwwwww"
,
'gztar'
, root_dir
=
'/Users/ryan/Downloads/test'
)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
def
make_archive(base_name,
format
, root_dir
=
None
, base_dir
=
None
, verbose
=
0
,
dry_run
=
0
, owner
=
None
, group
=
None
, logger
=
None
):
"""Create an archive file (eg. zip or tar).
'base_name' is the name of the file to create, minus any format-specific
extension; 'format' is the archive format: one of "zip", "tar", "bztar"
or "gztar".
'root_dir' is a directory that will be the root directory of the
archive; ie. we typically chdir into 'root_dir' before creating the
archive. 'base_dir' is the directory where we start archiving from;
ie. 'base_dir' will be the common prefix of all files and
directories in the archive. 'root_dir' and 'base_dir' both default
to the current directory. Returns the name of the archive file.
'owner' and 'group' are used when creating a tar archive. By default,
uses the current owner and group.
"""
save_cwd
=
os.getcwd()
if
root_dir
is
not
None
:
if
logger
is
not
None
:
logger.debug(
"changing into '%s'"
, root_dir)
base_name
=
os.path.abspath(base_name)
if
not
dry_run:
os.chdir(root_dir)
if
base_dir
is
None
:
base_dir
=
os.curdir
kwargs
=
{
'dry_run'
: dry_run,
'logger'
: logger}
try
:
format_info
=
_ARCHIVE_FORMATS[
format
]
except
KeyError:
raise
ValueError,
"unknown archive format '%s'"
%
format
func
=
format_info[
0
]
for
arg, val
in
format_info[
1
]:
kwargs[arg]
=
val
if
format
!
=
'zip'
:
kwargs[
'owner'
]
=
owner
kwargs[
'group'
]
=
group
try
:
filename
=
func(base_name, base_dir,
*
*
kwargs)
finally
:
if
root_dir
is
not
None
:
if
logger
is
not
None
:
logger.debug(
"changing back to '%s'"
, save_cwd)
os.chdir(save_cwd)
return
filename
|
shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
1
|
import
zipfile
|
# 压缩
1
2
3
4
|
z
=
zipfile.ZipFile(
'laxi.zip'
,
'w'
)
z.write(
'a.log'
)
z.write(
'data.data'
)
z.close()
|
# 解压
1
2
3
|
z
=
zipfile.ZipFile(
'laxi.zip'
,
'r'
)
z.extractall()
z.close()
|
zipfile 压缩解压
1
|
import
tarfile
|
# 压缩
1
2
3
4
|
tar
=
tarfile.
open
(
'your.tar'
,
'w'
)
tar.add(
'/Users/ryan/PycharmProjects/bbs2.zip'
, arcname
=
'bbs2.zip'
)
tar.add(
'/Users/ryan/PycharmProjects/cmdb.zip'
, arcname
=
'cmdb.zip'
)
tar.close()
|
# 解压
1
2
3
|
tar
=
tarfile.
open
(
'your.tar'
,
'r'
)
tar.extractall()
# 可设置解压地址
tar.close()
|
九、time
时间相关的操作,时间有三种表示方式:
时间戳 1970年1月1日之后的秒,即:time.time()
格式化的字符串 2014-11-11 11:11, 即:time.strftime('%Y-%m-%d')
结构化时间 元组包含了:年、日、星期等... time.struct_time 即:time.localtime()
print
time.time()
print
time.mktime(time.localtime())
print
time.gmtime()
#可加时间戳参数
print
time.localtime()
#可加时间戳参数
print
time.strptime(
'2014-11-11'
,
'%Y-%m-%d'
)
print
time.strftime(
'%Y-%m-%d'
)
#默认当前时间
print
time.strftime(
'%Y-%m-%d'
,time.localtime())
#默认当前时间
print
time.asctime()
print
time.asctime(time.localtime())
print
time.ctime(time.time())
import
datetime
'''
datetime.date:表示日期的类。常用的属性有year, month, day
datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond
datetime.datetime:表示日期时间
datetime.timedelta:表示时间间隔,即两个时间点之间的长度
timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]])
strftime("%Y-%m-%d")
'''
import
datetime
print
datetime.datetime.now()
print
datetime.datetime.now()
-
datetime.timedelta(days
=
5
)
十、re
re模块用于对python的正则表达式的操作。
字符:
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
次数:
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
IP:^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$ 手机号:^1[3|4|5|8][0-9]\d{8}$
1、match(pattern, string, flags=0)
从起始位置开始根据模型去字符串中匹配指定内容,匹配单个
正则表达式
要匹配的字符串
标志位,用于控制正则表达式的匹配方式
import re obj = re.match('\d+', '123uuasf')if obj: print obj.group()
# flags
I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case
L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale
U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale
M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline
S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline
X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments
flags
2、search(pattern, string, flags=0)
根据模型去字符串中匹配指定内容,匹配单个
import re obj = re.search('\d+', 'u123uu888asf')if obj: print obj.group()
3、group和groups
a = "123abc456"
print re.search("([0-9]*)([a-z]*)([0-9]*)", a).group()
print re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(0)
print re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1)
print re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(2)
print re.search("([0-9]*)([a-z]*)([0-9]*)", a).groups()
4、findall(pattern, string, flags=0)
上述两中方式均用于匹配单值,即:只能匹配字符串中的一个,如果想要匹配到字符串中所有符合条件的元素,则需要使用 findall。
import re obj = re.findall('\d+', 'fa123uu888asf')print obj
5、sub(pattern, repl, string, count=0, flags=0)
用于替换匹配的字符串
content = "123abc456"new_content = re.sub('\d+', 'sb', content)# new_content = re.sub('\d+', 'sb', content, 1)print new_content
相比于str.replace功能更加强大
6、split(pattern, string, maxsplit=0, flags=0)
根据指定匹配进行分组
content = "'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'"new_content = re.split('\*', content)# new_content = re.split('\*', content, 1)print new_content
content = "'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'"new_content = re.split('[\+\-\*\/]+', content)# new_content = re.split('\*', content, 1)print new_content
inpp = '1-2*((60-30 +(-40-5)*(9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))'inpp = re.sub('\s*','',inpp) new_content = re.split('\(([\+\-\*\/]?\d+[\+\-\*\/]?\d+){1}\)', inpp, 1)print new_content
相比于str.split更加强大
十一、random
随机数
import random
print
random.random()
#随机生成一个小数
1
2
3
4
5
6
|
>>>
print
random.random()
0.932943374323
>>>
print
random.random()
0.791924942212
>>>
print
random.random()
0.936765303812
|
print
random.randint(
1
,
2
)
#在1~2之间生成一个整数
1
2
3
4
5
6
7
|
>>>
print
random.randint(
1
,
2
)
2
>>>
print
random.randint(
1
,
2
)
2
>>>
print
random.randint(
1
,
2
)
1
>>>
|
print
random.randrange(
1
,
10
)
#在1~10这个区间随机生成一个数字
1
2
3
4
5
6
7
8
9
10
11
|
>>>
print
random.randrange(
1
,
10
)
6
>>>
print
random.randrange(
1
,
10
)
1
>>>
print
random.randrange(
1
,
10
)
2
>>>
print
random.randrange(
1
,
10
)
3
>>>
print
random.randrange(
1
,
10
)
2
>>>
|
随机验证码实例:
1
2
3
4
5
6
7
8
9
10
|
import
random
checkcode
=
''
for
i
in
range
(
4
):
current
=
random.randrange(
0
,
4
)
if
current !
=
i:
temp
=
chr
(random.randint(
65
,
90
))
else
:
temp
=
random.randint(
0
,
9
)
checkcode
+
=
str
(temp)
print
checkcode
|
运行结果为:
1
2
3
4
5
6
7
8
9
10
11
|
[www@Python auto]$ python randomnum.py
SKOC
[www@Python auto]$ python randomnum.py
Y8IJ
[www@Python auto]$ python randomnum.py
6UNB
[www@Python auto]$ python randomnum.py
Q79T
[www@Python auto]$ python randomnum.py
TPSQ
[www@Python auto]$
|