【IO】01、文件对象

  1. 云栖社区>
  2. 博客>
  3. 正文

【IO】01、文件对象

技术小甜 2017-11-14 19:18:00 浏览943
展开阅读全文

一、打开和关闭文件

1、文件打开和关闭

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
In [1]: help(open)
 
Help on built-in function open in module io:
 
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
    Open file and return a stream.  Raise IOError upon failure.
     
    ========= ===============================================================
    Character Meaning
    --------- ---------------------------------------------------------------
    'r'       open for reading (default)
    'w'       open for writing, truncating the file first
    'x'       create a new file and open it for writing
    'a'       open for writing, appending to the end of the file if it exists
    'b'       binary mode
    't'       text mode (default)
    '+'       open a disk file for updating (reading and writing)
    'U'       universal newline mode (deprecated)
    ========= ===============================================================     
     
In [6]: f = open("/tmp/shell/test.txt")  # 打开一个文件,获得一个文件对象
 
In [7]: type(f)
Out[7]: _io.TextIOWrapper
 
In [8]: f
Out[8]: <_io.TextIOWrapper name='/tmp/shell/test.txt' mode='r' encoding='UTF-8'>
 
In [9]: f.mode  # 文件对象的打开模式
Out[9]: 'r'
 
In [11]: f.name  # 文件名 
Out[11]: '/tmp/shell/test.txt'
 
In [13]: f.read()  # 读取文件的内容
Out[13]: 'Hello World!\nI love python\n'
 
In [15]: f.readable()  # 是否可读
Out[15]: True
 
In [16]: f.writable()  # 是否可写
Out[16]: False
 
In [17]: f.closed  # 文件对象是否关闭
Out[17]: False
 
 
In [20]: f.close()  # 关闭文件对象
 
In [21]: f.name
Out[21]: '/tmp/shell/test.txt'
 
In [22]: f.read()  # 关闭后不能再查看了
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-22-bacd0e0f09a3> in <module>()
----> 1 f.read()
 
ValueError: I/O operation on closed file.
 
In [25]: f.closed
Out[25]: True

  文件对象的操作和打开方式是相关


2、open函数mode参数详解

 1)控制读写的模式

 'r' :即mode=r,默认,只读打开,不可写;当文件不存在时,会抛出FileNotFoundError     
 'w':只写打开,不可读;会清空原文件(既使打开后没有做任何操作也会清空),当文件不存在时,会新建
 'x' :仅新建文件,只写打开,不可读;当文件存在时,会抛出FileExistError    
 'a' :追加内容到文件末尾(最后一行的下面一行),只写,不可读;当文件不存在时,会新建


从读写的方面来看,只有r可读不可写,其它都是可写不可读

当文件不存在时,只有r抛出异常,其它的都创建新文件

当文件存在时,只有x抛出异常

从是否影响文件原始内容来看,只有w会清空文件


 2)控制打开方式的模式

't':以文本模式打开,默认,读出和写入的是字符串;按字符操作

'b' :以二进制的模式打开,读出和写入的都是bytes;按字节操作

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
In [85]: f = open('/root/1.txt', mode='w')
 
In [86]: f.write('马哥Python')
Out[86]: 8                               # 按字符写入,写入了8个字符
 
In [87]: f.close()
 
In [88]: cat /root/1.txt
马哥Python
 
In [92]: f = open('/root/1.txt', mode='wb')
 
In [93]: f.write('马哥 Python')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-93-582947144dc2> in <module>()
----> 1 f.write('马哥 Python')
 
TypeError: a bytes-like object is required, not 'str'
 
In [94]: f.write('马哥 Python'.encode())
Out[94]: 13                                  # 按字节写入,写入了13个字节        
 
In [95]: f.close()
 
In [96]: f = open('/root/1.txt')
 
In [97]: f.read()
Out[97]: '马哥 Python'
 
In [98]: f.close()
 
In [99]: f = open('/root/1.txt', mode='rb')
 
In [100]: f.read()
Out[100]: b'\xe9\xa9\xac\xe5\x93\xa5 Python'

注意:

    mode的参数rw不能一起写:mode='rw',mode里必须有且仅有rwax中的一种,不指定则默认rt


'+':可读可写;+不能单独使用,

        会增加额外的读写操作,也就是说原来是只读的,会增加可写的操作,原来只写的,增加可读的操作,但不改变其它行为

       r+:可读可写,从当前指针覆盖写,

       w+:可读可写,先清空文件,

       a+:可读可写,从文件末尾追加(第一次写总是在文件末尾追加,尽管写之前移动了指针)

'U':已被废弃


3、文件位置指针

当open()打开一个文件的时候,解释器会持有一个指针,指向文件的某个位置

当我们读写文件时,总是从指针处开始向后操作,并且移动指针

当mode=r(或w,w会先清空文件)时,指针是指向0(文件的开始)

当mode=a时,指针指向EOF(End Of File 文件末尾)


查看当前文件的指针的位置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
In [7]: help(f.tell)
 
Help on built-in function tell:
 
tell() method of _io.TextIOWrapper instance
    Return current stream position.
(END) 
 
In [1]: f = open('/root/passwd')
 
In [2]: f.tell()
Out[2]: 0
 
In [3]: f.readline()
Out[3]: 'root:x:0:0:root:/root:/bin/bash\n'
 
In [4]: f.tell()
Out[4]: 32
 
In [5]: f.readline()
Out[5]: 'bin:x:1:1:bin:/bin:/sbin/nologin\n'
 
In [6]: f.tell()
Out[6]: 65


移动文件指针的位置:

seek()有2个参数:

   cookie  表示移动到哪里

   whence  表示从哪个位置开始移动,有3个值

          0:表示文件的开头,默认

          1:表示当前指针的位置

          2:表示文件末尾

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
In [23]: help(f.seek)
 
Help on built-in function seek:
 
seek(cookie, whence=0, /) method of _io.TextIOWrapper instance
    Change stream position.
     
    Change the stream position to the given byte offset. The offset is
    interpreted relative to the position indicated by whence.  Values
    for whence are:
     
    * 0 -- start of stream (the default); offset should be zero or positive
    * 1 -- current stream position; offset may be negative
    * 2 -- end of stream; offset is usually negative
     
    Return the new absolute position.        
 
In [35]: f.tell()
Out[35]: 65
 
In [36]: f.seek(0)
Out[36]: 0
 
In [37]: f.tell()
Out[37]: 0
 
In [38]: f.readline()
Out[38]: 'root:x:0:0:root:/root:/bin/bash\n'
 
In [39]: f.tell()
Out[39]: 32
 
In [40]: f.seek(5)
Out[40]: 5
 
In [41]: f.tell()
Out[41]: 5
 
In [42]: f.readline()
Out[42]: 'x:0:0:root:/root:/bin/bash\n'
 
 
# whence不为0时,cookie必须为0
In [95]: f.seek(10,1)   
---------------------------------------------------------------------------
UnsupportedOperation                      Traceback (most recent call last)
<ipython-input-95-aa8451ab67ab> in <module>()
----> 1 f.seek(10,1)
 
UnsupportedOperation: can't do nonzero cur-relative seeks
 
In [96]: f.seek(0,2) 
Out[96]: 1184

mode=t 时:

    当whence为0(默认值)时,cookie(offset)可以是任意整数

    当whence为1或2时,cookie只能为0


mode=b 时:

    当whence为0(默认值)时,cookie(offset)可以是任意整数

    当whence为1或2时,cookie也可以是任意整数


小结:

    seek()可以向后超出范围(但总是从文件末尾开始写),但不能向前超出范围;当seek()超出文件末尾时,不会有有异常,tell()返回的值也会超出文件末尾,但是写数据的时候,还是会从文件末尾开始写,而不是tell()返回的超过的值;即 write操作从Min(EOF,tell())中小的处开始

    seek(),tell()总是以字节来计算


4、buffering

    缓冲区设置

f.flush()、f.close()和f.seek()会刷新缓冲区


buffering=-1,默认值,8192个字节,超过这个值会自动刷新缓冲区的内容,再写

二进制模式:缓冲区大小为 io.DEFAULT_BUFFER_SIZE

文本模式:缓冲区大小为 io.DEFAULT_BUFFER_SIZE

1
2
3
4
In [48]: import io
 
In [49]: io.DEFAULT_BUFFER_SIZE
Out[49]: 8192

buffering=0,关闭缓冲区(不启用缓冲区)

二进制模式:unbuffered 关闭缓冲区

文本模式:不允许

buffering=1

二进制模式:缓冲区大小为1

文本模式:line buffering  遇到换行符就flush

buffering > 1

二进制模式:buffering

    会先判断缓冲区剩余位置是否足够存放当前字节,如果不能,先flush,再把当前字节写入缓冲区,如果当前字节大于缓冲区大小,直接flush

文本模式:io.DEFAULT_BUFFER_SIZE

    如果当前字节加缓冲区中的字节,超出缓冲区大小,直接flush缓冲区和当前字节


注意:

       一般在读写问件时,不考虑buffering,但在socket时需要考虑

        特殊文件对象有特殊的刷新方式


二、文件对象

1、文件对象是可迭代对象

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
In [85]: cat /tmp/1.log
1234
 
5
5555
In [86]: f.tell()
Out[86]: 12
 
In [87]: for in f:     # 文件对象是可迭代对象,每次迭代一行
    ...:     print(i)
    ...:     
 
In [88]: f.seek(0)
Out[88]: 0
 
In [89]: for in f:
    ...:     print(i)
    ...:     
1234
 
 
 
5
 
5555
 
In [90]:


2、文件对象上下文管理

上下文管理:会在离开时自动关闭文件,但是不会开启新的作用域

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
In [141]: with open('/tmp/1.log') as f:
     ...:     print(f.read())
     ...:     f.wirte('sb')
     ...:     
1234
 
5
5555aaa
bbb
aaa
bbb
[aaa
bbb
]
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-141-d87fc5f222e1> in <module>()
      1 with open('/tmp/1.log') as f:
      2     print(f.read())
----> 3     f.wirte('sb')
      
 
AttributeError: '_io.TextIOWrapper' object has no attribute 'wirte'
 
In [142]: f.closed
Out[142]: True


3、File-like 类文件对象

 StringI0

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
In [189]: from io import StringIO
 
In [190]: sio = StringIO()
                                                          
In [190]: sio = StringIO()
 
In [191]: sio.readable()
Out[191]: True
 
In [193]: sio.writable()
Out[193]: True
 
In [194]: sio.write('python')
Out[194]: 6
 
In [195]: sio.seek(0)
Out[195]: 0
 
In [196]: sio.read()
Out[196]: 'python'
 
In [197]: sio.tell()
Out[197]: 6
 
In [198]: sio.getvalue()   # 将文件的内容全部读出来,不管指针在哪,并可以重复读取多次
Out[198]: 'python'

    类文件对象还有:BytesIO, socket

    StringIO和BytesIO对应于打开模式为t和b的文件对象


作用:

      在内存中模拟文件对象,速度更快

      类文件对象可以不close,但会占用内存


三、pathlib

    在python 3.4之前只有使用os.path这一种方法来操作路径

    os.path是以字符串的方式操作路径的

    在python 3.4引入了pathlib库以面向对象的方式来操作路径

1
2
3
4
5
6
7
8
9
In [196]: import pathlib
 
In [199]: pwd = pathlib.Path('.')  # .代表当前目录
 
In [200]: pwd
Out[200]: PosixPath('.')
 
In [206]: pwd.absolute()  # 绝对路径
Out[206]: PosixPath('/root/magedu/python3')


1、对目录的操作

1
2
3
4
5
6
7
8
In [209]: pwd
Out[209]: PosixPath('.')
 
In [210]: pwd.is_absolute()
Out[210]: False
 
In [211]: pwd.is_dir()
Out[211]: True

遍历目录:

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
In [212]: pwd.iterdir()  # 返回一个目录生成器
Out[212]: <generator object Path.iterdir at 0x7fee8a140e08>
 
In [213]: for in pwd.iterdir():
     ...:     i
     ...:     
 
In [214]: for in pwd.iterdir():  # 遍历目录,只遍历子目录,不会递归遍历
     ...:     print(i)
     ...:     
.ipynb_checkpoints
第一天.ipynb
nohup.out
.python-version
元组及其操作.ipynb
test
test.py
 
 
In [216]: for in pwd.iterdir():
     ...:     print(type(i))
     ...:     print(i)
     ...:     
<class 'pathlib.PosixPath'>     # 可以继续循环,实现递归遍历
.ipynb_checkpoints
<class 'pathlib.PosixPath'>
第一天.ipynb
<class 'pathlib.PosixPath'>
nohup.out
<class 'pathlib.PosixPath'>
.python-version
<class 'pathlib.PosixPath'>
元组及其操作.ipynb
<class 'pathlib.PosixPath'>
test
<class 'pathlib.PosixPath'>
test.py
 
In [217]: type(pwd)
Out[217]: pathlib.PosixPath
 
In [218]: print(type(pwd))
<class 'pathlib.PosixPath'>

创建文件:

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
In [219]: d = pathlib.Path('/tmp/1.txt')
 
In [220]: d.exists()
Out[220]: True
 
In [221]: d.mkdir(755)
---------------------------------------------------------------------------
FileExistsError                           Traceback (most recent call last)
<ipython-input-221-ea2331bf5a68> in <module>()
----> 1 d.mkdir(755)
 
/root/.pyenv/versions/3.6.1/lib/python3.6/pathlib.py in mkdir(self, mode, parents, exist_ok)
   1225         if not parents:
   1226             try:
-> 1227                 self._accessor.mkdir(self, mode)
   1228             except FileExistsError:
   1229                 if not exist_ok or not self.is_dir():
 
/root/.pyenv/versions/3.6.1/lib/python3.6/pathlib.py in wrapped(pathobj, *args)
    388         @functools.wraps(strfunc)
    389         def wrapped(pathobj, *args):
--> 390             return strfunc(str(pathobj), *args)
    391         return staticmethod(wrapped)
    392 
 
FileExistsError: [Errno 17] File exists: '/tmp/1.txt'
 
 
In [223]: d1 = pathlib.Path('/tmp/11.txt')  # 先创建一个对象
 
In [224]: d1.exists()   # 判断此对象不存在
Out[224]: False
 
 
In [225]: help(d1.mkdir)
 
Help on method mkdir in module pathlib:
 
mkdir(mode=511, parents=False, exist_ok=False) method of pathlib.PosixPath instance
 
# mode 指定权限
# parents 创建父目录,当父目录存在时会报错,当exist_ok=True时,不报错,就相当于shell命令的mkdir -p
 
 
In [226]: d1.mkdir(0o755)  # 新建目录,并指定权限,默认511;0o表示八进制
 
In [227]: d1.exists()
Out[227]: True
 
In [237]: ls -ld /tmp/11.txt
drwxr-xr-x 2 root root 4096 Nov  2 14:24 /tmp/11.txt/

删除目录:

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
In [239]: d1.rmdir()    # 只能删除空目录
 
In [240]: d1.exists()
Out[240]: False
 
In [246]: d2 = pathlib.Path('/tmp')
 
In [247]: d2.rmdir()
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-247-ffe14b7c0399> in <module>()
----> 1 d2.rmdir()
 
/root/.pyenv/versions/3.6.1/lib/python3.6/pathlib.py in rmdir(self)
   1273         if self._closed:
   1274             self._raise_closed()
-> 1275         self._accessor.rmdir(self)
   1276 
   1277     def lstat(self):
 
/root/.pyenv/versions/3.6.1/lib/python3.6/pathlib.py in wrapped(pathobj, *args)
    388         @functools.wraps(strfunc)
    389         def wrapped(pathobj, *args):
--> 390             return strfunc(str(pathobj), *args)
    391         return staticmethod(wrapped)
    392 
 
OSError: [Errno 39] Directory not empty: '/tmp'
 
# 非空目录如何删除,在后面学习


2、对文件和目录的通用操作

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
In [250]: f = pathlib.Path('/tmp/xj/a.txt')
In [250]: f = pathlib.Path('/tmp/xj/a.txt')
 
In [251]: f.exists()
Out[251]: False
 
In [252]: f.is_file()   # 当文件不存在时,is类方法返回的都是false
Out[252]: False
 
In [253]: f.is_dir()
Out[253]: False
 
 
 
In [257]: f = pathlib.Path('/tmp/src')
 
In [258]: f.exists()
Out[258]: True
 
In [259]: f.cwd()      # 获取当前工作目录
Out[259]: PosixPath('/root/magedu/python3')
 
In [260]: f.absolute()    # 获取绝对路径
Out[260]: PosixPath('/tmp/src')
 
In [261]: f.as_uri()      # 绝对路径转化为uri
Out[261]: 'file:///tmp/src'
 
 
In [265]: pathlib.Path('~')
Out[265]: PosixPath('~')
 
In [266]: pathlib.Path('~').expanduser()  # 将~转化为具体的用户家目录
Out[266]: PosixPath('/root')
 
In [275]: f.home()  # 获取家目录
Out[275]: PosixPath('/root')
 
 
如何一个路径是一个符号链接,修改符号链接的权限就需要使用lchmod
 
In [267]: f.name  # 基名,相当于basename
Out[267]: 'src'
 
In [278]: f.parent  # 相当于dirname
Out[278]: PosixPath('/tmp')
 
In [279]: f.parents  # 父类
Out[279]: <PosixPath.parents>
 
In [273]: f.owner()  # 文件属主
Out[273]: 'root'
 
In [274]: f.group()
Out[274]: 'root'
 
 
In [285]: f = pathlib.Path('/tmp/shell/not_exist.txt')
 
In [286]: f.exists()
Out[286]: True
 
In [287]: f.suffix   # 文件名的后缀(.后面的)
Out[287]: '.txt'
 
In [288]: f.suffixs
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-288-c25eaddee638> in <module>()
----> 1 f.suffixs
 
AttributeError: 'PosixPath' object has no attribute 'suffixs'
 
In [289]: f.suffixes
Out[289]: ['.txt']
 
In [290]: f = pathlib.Path('/tmp/shell/not_exist.txt.log')
 
In [291]: f.exists()
Out[291]: False
 
In [292]: f.suffixes        # 文件不存在也可以获取到
Out[292]: ['.txt''.log']
 
In [293]: f.suffix
Out[293]: '.log'

f.stat:文件状态

1
2
3
4
5
6
7
In [297]: f = pathlib.Path('/tmp/shell/not_exist.txt')
 
In [298]: f.stat()
Out[298]: os.stat_result(st_mode=33188, st_ino=530232, st_dev=2050, st_nlink=1, st_uid=0, st_gid=0, st_size=7, st_atime=1499241423, st_mtime=1499241417, st_ctime=1499241417)
 
In [299]: f.lstat()  # 针对符号链接本身
Out[299]: os.stat_result(st_mode=33188, st_ino=530232, st_dev=2050, st_nlink=1, st_uid=0, st_gid=0, st_size=7, st_atime=1499241423, st_mtime=1499241417, st_ctime=1499241417)

f.glob:通配符

f.rglob:递归遍历

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
In [307]: d = pathlib.Path('/tmp')
 
In [314]: for in d.glob('*/*.txt'):   # *表示当前目录
     ...:     print(i)
     ...:     
/tmp/src/helloworld.txt
/tmp/shell/python.txt
/tmp/shell/test.txt
/tmp/shell/not_exist.txt
 
In [315]: for in d.glob('**/*.txt'):   # **表示递归子目录
     ...:     print(i)
     ...:     
/tmp/1.txt
/tmp/src/helloworld.txt
/tmp/src/cdn/t2/t2_201706150000_charge.txt
/tmp/src/cdn/t2/t2_201706150000_role.txt
/tmp/src/cdn/t2/t2_201706150000_activity_record.txt
/tmp/src/cdn/t2/t2_201706150000_role_face.txt
/tmp/src/cdn/t2/t2_201706150000_enter_role_successful.txt
/tmp/src/cdn/t2/t2_201706150000_task_record.txt
/tmp/src/cdn/t2/t2_201706150000_user_login_success.txt
/tmp/src/cdn/t2/t2_201706150000_consumption_record.txt
/tmp/src/cdn/t2/t2_201706150000_user_login.txt
/tmp/src/cdn/t2/t2_201706150000_enter_scene.txt
/tmp/src/cdn/t2/t2_201706150000_mall_transactions.txt
/tmp/src/cdn/t2/t2_201706150000_enter_role.txt
/tmp/src/cdn/t2/t2_201706150000_props_record.txt
/tmp/shell/python.txt
/tmp/shell/test.txt
/tmp/shell/not_exist.txt
 
In [320]: for in d.rglob('*/*.txt'):  # gglob 递归遍历
     ...:     print(i)
     ...:     
/tmp/src/helloworld.txt
/tmp/shell/python.txt
/tmp/shell/test.txt
/tmp/shell/not_exist.txt
/tmp/src/cdn/t2/t2_201706150000_charge.txt
/tmp/src/cdn/t2/t2_201706150000_role.txt
/tmp/src/cdn/t2/t2_201706150000_activity_record.txt
/tmp/src/cdn/t2/t2_201706150000_role_face.txt
/tmp/src/cdn/t2/t2_201706150000_enter_role_successful.txt
/tmp/src/cdn/t2/t2_201706150000_task_record.txt
/tmp/src/cdn/t2/t2_201706150000_user_login_success.txt
/tmp/src/cdn/t2/t2_201706150000_consumption_record.txt
/tmp/src/cdn/t2/t2_201706150000_user_login.txt
/tmp/src/cdn/t2/t2_201706150000_enter_scene.txt
/tmp/src/cdn/t2/t2_201706150000_mall_transactions.txt
/tmp/src/cdn/t2/t2_201706150000_enter_role.txt
/tmp/src/cdn/t2/t2_201706150000_props_record.txt

路径的拼接:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
In [321]: '/' 'xj' '/sb'
Out[321]: '/xj/sb'
 
In [322]: pathlib.Path('/''home''xj''workspace')
Out[322]: PosixPath('/home/xj/workspace')
 
In [323]: pathlib.Path('home''xj''workspace')
Out[323]: PosixPath('home/xj/workspace')
 
In [324]: print(pathlib.Path('home''xj''workspace'))
home/xj/workspace
 
In [325]: print(pathlib.Path('/''home''xj''workspace'))
/home/xj/workspace
 
In [331]: print(pathlib.Path('/''/home''xj''workspace'))
/home/xj/workspace
 
In [331]: print(pathlib.Path('/''/home''xj''workspace'))
/home/xj/workspace
 
# 能自动添加和删除/,拼接路径更加方便


四、文件对象实现copy,move,rm

1、copy

shutil标准库

shutil.copyfileobj(fsrcfdst[length])                            # 2个文件对象间内容的copy

shutil.copyfile(srcdst*follow_symlinks=True)          # 仅复制内容,不复制元数据

  • shutil.copymode(srcdst*follow_symlinks=True)    # 仅复制权限

  • shutil.copystat(srcdst*follow_symlinks=True)    # 仅复制元数据

  • shutil.copy(srcdst*follow_symlinks=True)           # 复制文件内容和权限,相当于copyfile + copymode

  • shutil.copy2(srcdst*follow_symlinks=True)         #  复制文件内容和元数据,相当于copyfile + copystat

  • shutil.ignore_patterns(*patterns)

  • shutil.copytree(srcdstsymlinks=Falseignore=Nonecopy_function=copy2ignore_dangling_symlinks=False)

  • shutil.rmtree(pathignore_errors=Falseonerror=None)

  • shutil.move(srcdstcopy_function=copy2)


以上函数都只针对文件或当前这一层的目录

copyfileobj 操作的是文件对象,后面的函数都是操作路径


  • shutil.copytree(srcdstsymlinks=Falseignore=Nonecopy_function=copy2ignore_dangling_symlinks=False)

           递归复制目录,其中copy_function参数指定用何种方法复制文件,可以是以上函数中除了copyfileobj意外任意一个


  • shutil.rmtree(pathignore_errors=Falseonerror=None)

    递归删除目录,

    ignore_errors 表示是否忽略错误,onerror 表示如何处理错误,仅当ignore_errors=False时,onerror才生效,ignore_errors 为True是遇到错误直接抛出异常


2、move

  • shutil.move(srcdstcopy_function=copy2)

       具体实现依赖操作系统,如果操作系统实现了renmae系统调用,直接走rename系统调用,如果没有实现,先使用copytree复制,然后使用rmtree


  • shutil.disk_usage(path)

    Return disk usage statistics about the given path as a named tuple with the attributes totalused and free, which are the amount of total, used and free space, in bytes.

    New in version 3.3.

    Availability: Unix, Windows.


  • shutil.chown(pathuser=Nonegroup=None)

    Change owner user and/or group of the given path.

    user can be a system user name or a uid; the same applies to group. At least one argument is required.

    See also os.chown(), the underlying function.

    Availability: Unix.

    New in version 3.3.


  • shutil.which(cmdmode=os.F_OK | os.X_OKpath=None)

1
2
3
4
5
In [68]: shutil.which('python')
Out[68]: '/root/.pyenv/versions/commy/bin/python'
 
In [69]: shutil.which('ls')
Out[69]: '/bin/ls'

















本文转自xiexiaojun51CTO博客,原文链接: http://blog.51cto.com/xiexiaojun/1944844,如需转载请自行联系原作者

网友评论

登录后评论
0/500
评论
技术小甜
+ 关注