python之路-基础篇-第六周 目录 一、示例代码展示 二、os模块 三、sys模块 四、常用模块shutil 五、shelve模块 六、xml 七、configparser 八、hashlib模块 九、subprocess模块

一、示例代码展示

二、os模块

注意事项

os.system:执行shell,完成后关闭shell
os.rename:如果新的文件名存在,就会报错,不会覆盖
os.stat:可以获取文件的大小等信息
os.path.isfile:判断是否一个文件
os.path.join:拼接文件路径和文件名等
os.popen:将操作系统命令输出,保存下来

import os
#os.system("ls")
a = os.popen("ls").read()
print(a,type(a))

三、sys模块

四、常用模块shutil

shutil.copyfileobj() #拷贝打开的文件对象

fsrc = open("src.file", "r")  #需要以r打开
fdst = open("dst.file", "w")  #需要以w打开
import shutil
shutil.copyfileobj(fsrc, fdst)
#不管fdst文件中是否包含内容都能够覆盖,并执行成功。

shutil.copyfile() #直接拷贝文件

import shutil
shutil.copyfile("src.file", "dst.file")  #直接对文件进行复制

shutil.copymode() #仅拷贝权限,内容用户组等都不拷贝

#修改并查看两个文件的权限
import os
os.system("chmod 777 dst.file")  #将目标文件的权限改为777
os.system("ls -l | grep file")

import shutil
shutil.copymode("src.file", "dst.file")  #复制权限

os.system("ls -l | grep file")  #查看文件的权限

执行结果:
-rwxrwxrwx  1 yangfeilong  staff    7 Feb 22 10:35 dst.file
-rw-r--r--  1 yangfeilong  staff    6 Feb 22 10:36 src.file

-rw-r--r--  1 yangfeilong  staff    7 Feb 22 10:35 dst.file
-rw-r--r--  1 yangfeilong  staff    6 Feb 22 10:36 src.file

shutil.copystat() #拷贝状态信息 os.utime来改访问时间等

import os
print("src.file=>",os.stat("src.file"))    #打印两个文件的stat
print("dst.file=>",os.stat("dst.file"))
import shutil
shutil.copystat("src.file", "dst.file")
print("src.file=>",os.stat("src.file"))    #打印两个文件的stat
print("dst.file=>",os.stat("dst.file"))

执行结果:可以看到st_atime和st_mtime两个文件的值被修改成一致了。
src.file=> os.stat_result(st_mode=33188, st_ino=21936456, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=6, st_atime=1456109330, st_mtime=1456108568, st_ctime=1456108568)
dst.file=> os.stat_result(st_mode=33188, st_ino=21938280, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=10, st_atime=1456109336, st_mtime=1456109336, st_ctime=1456109336)

src.file=> os.stat_result(st_mode=33188, st_ino=21936456, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=6, st_atime=1456109330, st_mtime=1456108568, st_ctime=1456108568)
dst.file=> os.stat_result(st_mode=33188, st_ino=21938280, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=10, st_atime=1456109330, st_mtime=1456108568, st_ctime=1456109337)

shutil.copy() #文件内容和权限

#修改并查看两个文件的权限
import os
os.system("chmod 777 dst.file")  #将目标文件的权限改为777
os.system("ls -l | grep file")

import shutil
shutil.copy("src.file", "dst.file")  #复制文件内容和权限

os.system("ls -l | grep file")  #查看文件的权限
执行结果:文件内容和权限都被拷贝了。
-rwxrwxrwx  1 yangfeilong  staff   10 Feb 22 10:36 dst.file
-rw-r--r--  1 yangfeilong  staff    6 Feb 22 10:54 src.file

-rw-r--r--  1 yangfeilong  staff    6 Feb 22 10:54 dst.file
-rw-r--r--  1 yangfeilong  staff    6 Feb 22 10:54 src.file

shutil.copy2() #文件和状态信息

import os
os.system("chmod 777 dst.file")
os.system("ls -l | grep file")
print("src.file=>",os.stat("src.file"))
print("dst.file=>",os.stat("dst.file"))
import shutil
shutil.copy2("src.file", "dst.file")
os.system("ls -l | grep file")
print("src.file=>",os.stat("src.file"))
print("dst.file=>",os.stat("dst.file"))

执行结果:貌似连文件内容、权限和stat都拷贝啦。。。
-rwxrwxrwx  1 yangfeilong  staff    19 Feb 22 10:59 dst.file
-rw-r--r--  1 yangfeilong  staff    13 Feb 22 10:59 src.file
src.file=> os.stat_result(st_mode=33188, st_ino=21939968, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13, st_atime=1456109941, st_mtime=1456109941, st_ctime=1456109941)
dst.file=> os.stat_result(st_mode=33279, st_ino=21939967, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=19, st_atime=1456109941, st_mtime=1456109941, st_ctime=1456109941)

-rw-r--r--  1 yangfeilong  staff    13 Feb 22 10:59 dst.file
-rw-r--r--  1 yangfeilong  staff    13 Feb 22 10:59 src.file
src.file=> os.stat_result(st_mode=33188, st_ino=21939968, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13, st_atime=1456109941, st_mtime=1456109941, st_ctime=1456109941)
dst.file=> os.stat_result(st_mode=33188, st_ino=21939967, st_dev=16777220, st_nlink=1, st_uid=501, st_gid=20, st_size=13, st_atime=1456109941, st_mtime=1456109941, st_ctime=1456109941)

shutil.copytree() #递归拷贝,目标目录必须不存在

可以使用shutil.ignore_patterns()来排除一些文件,例如:copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*')) #拷贝目录,但是除了.pyc文件

import os
os.system("find tree_dst -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'")  #列出des目录树
import shutil
shutil.copytree("tree_src", "tree_dst", ignore=shutil.ignore_patterns('*.py','*.pyc'))  #排除py或者pyc文件
os.system("find tree_dst -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'")  #列出des目录树

执行结果:
find: tree_dst: No such file or directory    #目标目录需要不存在,否则报错
#拷贝完成后的tree
tree_dst
|____src1.file
|____src2.file
|____tree_src1
| |____src1.file
| |____src2.file

shutil.rmtree(path[, ignore_errors[, onerror]]) #删除树

import os
os.system("find tree_dst -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'")
import shutil
shutil.rmtree("tree_dst")
os.system("find tree_dst -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'")

执行结果:
tree_dst
|____src1.file
|____src2.file
|____tree_src1
| |____src1.file
| |____src2.file
find: tree_dst: No such file or directory

shutil.move(src, dst)递归移动文件

import os
os.system("find tree_dst -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'")
import shutil
shutil.move("tree_dst", "tree_dst_new")
os.system("find tree_dst -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'")
os.system("find tree_dst_new -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'")

执行结果:
tree_dst
|____src1.file
|____src2.file
|____tree_src1
| |____src1.file
| |____src2.file
find: tree_dst: No such file or directory   #老的目录被删除了
tree_dst_new
|____src1.file
|____src2.file
|____tree_src1
| |____src1.file
| |____src2.file

shutil.make_archive(base_name, format,...) #创建归档,压缩包

创建压缩包并返回文件路径,例如:zip、tar、gztar

#打包文件:
import shutil
shutil.make_archive("src.file","tar",root_dir=".")  #用tar格式 root_dir默认为当前路径。
import os
os.system("ls -l | grep src.file")

执行结果:
-rw-r--r--  1 yangfeilong  staff     13 Feb 22 10:59 src.file
-rw-r--r--  1 yangfeilong  staff  20480 Feb 22 11:28 src.file.tar
#打包目录
import shutil
shutil.make_archive("tree_src","gztar",root_dir=".")  #以gztar方式打包压缩,root_dir默认为当前路径。
import os
os.system("ls -l | grep tree_src")

执行结果:
drwxr-xr-x  5 yangfeilong  staff    170 Feb 22 11:04 tree_src
-rw-r--r--  1 yangfeilong  staff   1209 Feb 22 11:30 tree_src.tar.gz

zipfile模块

#压缩:
import zipfile
z = zipfile.ZipFile("a.zip", "w")
z.write("src.file")
z.write("dst.file")
z.close()
import os
os.system("ls -l | grep a.zip")

result:
-rw-r--r--  1 yangfeilong  staff    232 Feb 22 11:39 a.zip
#解压:
import zipfile
z = zipfile.ZipFile("a.zip", "r")
z.extractall()
z.close()
import os
os.system("ls -l | grep .file")

result:貌似会修改原有文件的stat
-rw-r--r--  1 yangfeilong  staff     13 Feb 22 11:41 dst.file
-rw-r--r--  1 yangfeilong  staff     13 Feb 22 11:41 src.file

tarfile模块

#压缩:
import tarfile
t = tarfile.open("b.tar", "w")
t.add("src.file")
t.add("dst.file")
t.close()
import os
os.system("ls -l | grep b.tar")

result:
-rw-r--r--  1 yangfeilong  staff  10240 Feb 22 11:45 b.tar
#解压:
import tarfile
t = tarfile.open("b.tar", "r")
t.extractall()
t.close()
import os
os.system("ls -l | grep .file")

result:貌似能保持原有文件的stat
-rw-r--r--  1 yangfeilong  staff     13 Feb 22 11:41 dst.file
-rw-r--r--  1 yangfeilong  staff     13 Feb 22 11:41 src.file

五、shelve模块

shelve模块是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式

#序列化
class Test(object):     #定义类
   def __init__(self, n):
       self.n = n
t1 = Test(1111)    #实例化
t2 = Test(2222)    #实例化

t3_dict = ["alex",12,"IT"]   #来个字典

import shelve
d = shelve.open("shelve_test")
d["d1"] = t1    #把这三个东西序列化,使用key,vaules的方式
d["d2"] = t2
d["d3"] = t3_dict
d.close()
#反序列化
>>> import shelve
>>> a = shelve.open("shelve_test")
>>> a
<shelve.DbfilenameShelf object at 0x101adae80>
>>> a.get("d1")
<ex.Test object at 0x101d310b8>
>>> a.get("d2")
<ex.Test object at 0x101aea8d0>
>>> a.get("d3")
['alex', 12, 'IT']
>>> a.get("d2").n
2222
>>> a.get("d1").n
1111
>>> 

发现一个问题,在使用shelve反序列化的时候,如果我把原来序列化的代码注释掉,就会出现下面的问题。啥情况?
所以一定要保留类定义的文件。

#
y-pc:day06 yangfeilong$ python3
Python 3.5.1 (v3.5.1:37a07cee5969, Dec  5 2015, 21:12:44) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import shelve
>>> a = shelve.open("shelve_test")
>>> a.get("d3")
['alex', 12, 'IT']
>>> a.get("d1")
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/shelve.py", line 111, in __getitem__
    value = self.cache[key]
KeyError: 'd1'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/shelve.py", line 106, in get
    return self[key]
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/shelve.py", line 114, in __getitem__
    value = Unpickler(f).load()
AttributeError: Can't get attribute 'Test' on <module 'ex' from '/Users/yangfeilong/GitHub/python/day06/ex.py'>

使用pickle模块多次dump

多次dump和多次的load可以存取多个数据,但是保持着先进先出的特性。
与shelve相比,缺少像shelve那种key,vaule的键值对的容易读取和使用的优势。

#序列化:
class Test(object):
   def __init__(self, n):
       self.n = n
t1 = Test(1111)
t2 = Test(2222)

t3_dict = ["alex",12,"IT"]


import pickle
f = open("pickle_test.pkl","wb")
pickle.dump(t1, f)   #先进先出的管道
pickle.dump(t2, f)
pickle.dump(t3_dict, f)
f.close()
#反序列化:
>>> import pickle
>>> 
>>> f = open("pickle_test.pkl","rb")
>>> a = pickle.load(f)  #先进先出的管道
>>> b = pickle.load(f)
>>> c = pickle.load(f)
>>> f.close()
>>> print(a)
<ex.Test object at 0x101aea358>
>>> print(a.n)
1111
>>> print(b,b.n)
<ex.Test object at 0x101adae80> 2222
>>> print(c)
['alex', 12, 'IT']
>>> 

六、xml

七、configparser

Apache,mysql,openstack等配置文件都是这个写的,很常见,那么如何读写配置文件呢?
写配置文件

#写配置文件
import configparser
config = configparser.ConfigParser()  #获取一个配置文件的实例

#编写配置文件
config["DEFAULT"] = {   
    "Server":45,
    "Client":12,
}

#编写配置文件
config["bitbuckit.org"] = {}
config["bitbuckit.org"]["User"] = "yangfl"
config["bitbuckit.org"]["Port"] = "5050"

#写入文件
with open("config.conf", "w") as f:
    config.write(f)

配置文件编写完成如下:config.conf
[DEFAULT]
server = 45
client = 12

[bitbuckit.org]
user = yangfl
port = 5050

读配置文件

>>> import configparser  #导入模块
>>> config = configparser.ConfigParser()  #实例化
>>> config.sections()  #查看内容,无
[]
>>> config.read("config.conf")  #读入配置文件
['config.conf']
>>> config.sections()   #查看
['bitbuckit.org']
>>> 
>>> a = config.sections()
>>> type(a)
<class 'list'>
>>> a
['bitbuckit.org']
>>> config['bitbuckit.org']   #查看配置文件中的非default参数,在['bitbuckit.org']也能够取到default的所有参数。
<Section: bitbuckit.org>
>>> config['bitbuckit.org']["user"]
'yangfl'
>>> config['bitbuckit.org']["User"]
'yangfl'
>>> config.defaults()   #查看DEFAULT下的参数,DEFAULT表示的是全局参数
OrderedDict([('server', '45'), ('client', '12')])

八、hashlib模块

加密

import hashlib
hash = hashlib.sha512()
hash.update('admin'.encode())
print(hash.hexdigest())
hash.update("123".encode())
print(hash.hexdigest())
#c7ad44cbad762a5da0a452f9e854fdc1e0e7a52a38015f23f3eab1d80b931dd472634dfac71cd34ebc35d16ab7fb8a90c81f975113d6c7538dc69dd8de9077ec
#7fcf4ba391c48784edde599889d6e3f1e47a27db36ecc050cc92f259bfac38afad2c68a1ae804d77075e8fb722503f3eca2b2c1006ee6f6c7b7628cb45fffd1d


import hmac
h = hmac.new("yangfl".encode())
h.update("hello hello.".encode())
print(h.hexdigest())
#ae3c749e41d45e76c038b0eda861a785

九、subprocess模块

可以生成一个进程,处理输入输出错误等,将来会替换os.system和os.spawn模块

  • python2.x中使用call成员
  • python3.x使用run方法
  • 需要复杂交互情况使用Popen方法。
import subprocess

#下面三个等价
subprocess.run(["ls", "-l"])
subprocess.run("ls -l ", shell = True)
subprocess.call(["ls", "-l"])

#
a = subprocess.run("ls -l ", shell = True, stdout = subprocess.PIPE)
print(a)
b = subprocess.call("ls -l ", shell = True, stdout = subprocess.PIPE)
print(b)
c = subprocess.Popen("ls -l ", shell = True, stdout = subprocess.PIPE)
print(c)

未完待续