上下文管理、路径操作、序列化

一、上下文管理

In [2]: lst = []

In [3]: for i in range(1000):
   ...:     lst.append(open('./hello.py'))
   ...:     

In [4]: len(lst)
Out[4]: 1000

In [5]: for i in range(1000):
   ...:     lst.append(open('./hello.py'))
   ...:     
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-5-0b1b3d821ecd> in <module>()
      1 for i in range(1000):
----> 2     lst.append(open('./hello.py'))
      3 

OSError: [Errno 24] Too many open files: './hello.py'

In [6]: for x in lst:
   ...:     x.close()
   ...:     

In [7]: f = open('./hello.py')

In [8]: f.close()

In [9]: 

1、上下文管理 方法      

with open() as f:
    pass   
​
In [9]: f = open('./hello.py')      # 由于第二步报错,所以第三步的close操作没有被正常执行。
   ...: f.write('abc')
   ...: f.close()
   ...: 
---------------------------------------------------------------------------
UnsupportedOperation                      Traceback (most recent call last)
<ipython-input-9-9d43d4b0758e> in <module>()
      1 f = open('./hello.py')
----> 2 f.write('abc')
      3 f.close()

UnsupportedOperation: not writable

In [10]: f.fileno()
Out[10]: 11

In [11]: f.closed                    # 由于第二步报错,所以第三步的close操作没有被正常执行。
Out[11]: False

In [12]: f = open('./hello.py')      # 常规解决方法 
    ...: try:
    ...:     f.write('123')
    ...: finally:
    ...:     f.close()
    ...:     
---------------------------------------------------------------------------
UnsupportedOperation                      Traceback (most recent call last)
<ipython-input-12-0841de49e228> in <module>()
      1 f = open('./hello.py')               
      2 try:
----> 3     f.write('123')
      4 finally:
      5     f.close()

UnsupportedOperation: not writable

In [13]: f.closed
Out[13]: True

In [14]: 

In [14]: with open('hello.py') as f:    # python 解决方法
    ...:     pass
    ...: 

In [15]: f.closed
Out[15]: True

In [16]: f.name
Out[16]: 'hello.py'

In [17]: %pwd
Out[17]: '/home/magedu'

In [18]: with open('/home/magedu/hello.py') as f:
    ...:     pass
    ...: 

In [19]: f.name           # f.name 返回的并非是 f 的名字;而是with...open() as f: 中open()内传入的名字
Out[19]: '/home/magedu/hello.py'

In [20]: 


In [6]: from io import StringIO

In [7]: sio = StringIO()        # File-Like对象,文本模式

In [8]: sio.readable()
Out[8]: True

In [9]: sio.write('abcd')
Out[9]: 4

In [10]: sio.read()
Out[10]: ''

In [11]: sio.flush()

In [12]: sio.read()
Out[12]: ''

In [13]: sio.seek(0)
Out[13]: 0

In [14]: sio.read()
Out[14]: 'abcd'

In [15]: sio.getvalue()
Out[15]: 'abcd'

In [16]: sio.write('qwe')
Out[16]: 3

In [17]: sio.getvalue()
Out[17]: 'abcdqwe'

In [18]: sio.close()

In [19]: 
In [19]: from io import BytesIO  # 二进制模式

In [20]: bio = BytesIO()

In [21]: bio.write(b'abc')
Out[21]: 3

In [22]: bio.seek(0)
Out[22]: 0

In [23]: bio.read()
Out[23]: b'abc'

In [24]: bio.close()

In [25]: bio.getvalue()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-25-6be49df4471b> in <module>()
----> 1 bio.getvalue()

ValueError: I/O operation on closed file.

In [26]: 

StringIO 和 BytesIO 是子集,类文件对象是超集

In [27]: bio = BytesIO()

In [28]: buf = bio.getbuffer()

In [29]: bio.close()
---------------------------------------------------------------------------
BufferError                               Traceback (most recent call last)
<ipython-input-29-dc4312aa1350> in <module>()
----> 1 bio.close()

BufferError: Existing exports of data: object cannot be re-sized

In [30]: buf.release()

In [31]: bio.close()

In [32]: 

二、路径的操作

In [33]: import os  # 以字符串的形式进行操作

In [34]: import pathlib # 使用OO 的方式进行操作,Object Oriented(面向对象) 

In [35]: cwd = pathlib.Path('.')

In [36]: cwd
Out[36]: PosixPath('.')

In [37]: help(cwd)

Help on PosixPath in module pathlib object:

Help on PosixPath in module pathlib object:

class PosixPath(Path, PurePosixPath)
 |  PurePath represents a filesystem path and offers operations which
 |  don't imply any actual filesystem I/O.  Depending on your system,
 |  instantiating a PurePath will return either a PurePosixPath or a
 |  PureWindowsPath object.  You can also instantiate either of these classes
 |  directly, regardless of your system.
 |  
 |  Method resolution order:
 |      PosixPath
 |      Path
 |      PurePosixPath
 |      PurePath
 |      builtins.object
 |  
 |  Methods inherited from Path:
 |  
 |  __enter__(self)
 |  
 |  __exit__(self, t, v, tb)
 |  
 |  absolute(self)
 |      Return an absolute version of this path.  This function works
 |      even if the path doesn't point to anything.
 |      
 |      No normalization is done, i.e. all '.' and '..' will be kept along.
 |      Use resolve() to get the canonical path to a file.
# ...略
In [39]: cwd.is_dir()   # 此路径是否为目录
Out[39]: True

In [40]: cwd.iterdir()  # 使cwd 可遍历         
Out[40]: <generator object Path.iterdir at 0x7f94d24421a8>

In [41]: for i in cwd:
    ...:     print(i)
    ...:     
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-41-5477fd409326> in <module>()
----> 1 for i in cwd:
      2     print(i)
      3 

TypeError: 'PosixPath' object is not iterable

In [42]: for i in cwd.iterdir():
    ...:     print(type(i), i)
    ...:     
<class 'pathlib.PosixPath'> .ICEauthority
<class 'pathlib.PosixPath'> .bash_logout
<class 'pathlib.PosixPath'> .sogouinput
<class 'pathlib.PosixPath'> 下载
<class 'pathlib.PosixPath'> .gnome2_private
<class 'pathlib.PosixPath'> 公共的
# ... 略
In [43]: cwd.mkdir('abcd')  # 在指定的路径创建一个新目录
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-43-632e6b8cf3ec> in <module>()
----> 1 cwd.mkdir('abcd')

~/.pyenv/versions/3.6.3/lib/python3.6/pathlib.py in mkdir(self, mode, parents, exist_ok)
   1224             self._raise_closed()
   1225         try:
-> 1226             self._accessor.mkdir(self, mode)
   1227         except FileNotFoundError:
   1228             if not parents or self.parent == self:

~/.pyenv/versions/3.6.3/lib/python3.6/pathlib.py in wrapped(pathobj, *args)
    385         @functools.wraps(strfunc)
    386         def wrapped(pathobj, *args):
--> 387             return strfunc(str(pathobj), *args)
    388         return staticmethod(wrapped)
    389 

TypeError: an integer is required (got type str)

In [44]: d = pathlib.Path('./abcd')

In [45]: d.exists()   # 判断这条路径 是否存在
Out[45]: False

In [46]: d.mkdir(0o755)

In [47]: %ls -ld ./abcd
drwxr-xr-x 2 root root 4096 11月 13 23:09 ./abcd/

In [48]: 0o755
Out[48]: 493

In [49]: 0o777      # 777 是一个 八进制的777, 输出是十进制的数
Out[49]: 511

In [50]: help(d.mkdir)

Help on method mkdir in module pathlib:

mkdir(mode=511, parents=False, exist_ok=False) method of pathlib.PosixPath instance
    Create a new directory at this given path.
~

(END)

In [51]: 0xa
Out[51]: 10

In [52]: 0b10
Out[52]: 2

In [53]: 
In [58]: d = pathlib.Path('./ab/cd/ef')

In [59]: d.mkdir(0o755, parents=True)  # parents 参数帮我们实现级联创建 
---------------------------------------------------------------------------
FileExistsError                           Traceback (most recent call last)
<ipython-input-59-e309af38104f> in <module>()
----> 1 d.mkdir(0o755, parents=True)  # parents 参数帮我们实现级联创建

~/.pyenv/versions/3.6.3/lib/python3.6/pathlib.py in mkdir(self, mode, parents, exist_ok)
   1224             self._raise_closed()
   1225         try:
-> 1226             self._accessor.mkdir(self, mode)
   1227         except FileNotFoundError:
   1228             if not parents or self.parent == self:

~/.pyenv/versions/3.6.3/lib/python3.6/pathlib.py in wrapped(pathobj, *args)
    385         @functools.wraps(strfunc)
    386         def wrapped(pathobj, *args):
--> 387             return strfunc(str(pathobj), *args)
    388         return staticmethod(wrapped)
    389 

FileExistsError: [Errno 17] File exists: 'ab/cd/ef'

In [60]: %ls -lR   
.:
总用量 1644
-rw-rw-r-- 1 magedu magedu  11964 11月  5 11:42 1.docx
drwxr-xr-x 3 root   root     4096 11月 12 22:59 ab/

# ... 略

./ab:
总用量 4
drwxr-xr-x 3 root root 4096 11月 12 22:59 cd/

./ab/cd:
总用量 4
drwxr-xr-x 2 root root 4096 11月 12 22:59 ef/

./ab/cd/ef:
总用量 0

./abcd:
总用量 0

./My Music:
总用量 0

./My Pictures:
总用量 0

./My Videos:
总用量 0
# ... 略  
   
In [68]: d.mkdir(0o755, parents=True, exist_ok=True)     # exist_ok 若文件夹存在,也不会报错

In [69]: f = pathlib.Path('./ab/cd/a.txt')

In [70]: f.exists()     # f.exists() 可以用来判断 这个文件(或文件夹)是否存在。
Out[70]: False

In [71]: f.is_file()
Out[71]: False

In [72]: f.is_dir()
Out[72]: False

In [73]: f.is_absolute()
Out[73]: False

In [74]: 

In [19]: d.rmdir()

In [20]: d = pathlib.Path('./ab/')

In [21]: d.rmdir()     # rmdir 删除路径的操作,要求必须是空目录
---------------------------------------------------------------------------
OSError                                   Traceback (most recent call last)
<ipython-input-21-b1299da09e5c> in <module>()
----> 1 d.rmdir()

~/.pyenv/versions/3.6.3/lib/python3.6/pathlib.py in rmdir(self)
   1268         if self._closed:
   1269             self._raise_closed()
-> 1270         self._accessor.rmdir(self)
   1271 
   1272     def lstat(self):

~/.pyenv/versions/3.6.3/lib/python3.6/pathlib.py in wrapped(pathobj, *args)
    385         @functools.wraps(strfunc)
    386         def wrapped(pathobj, *args):
--> 387             return strfunc(str(pathobj), *args)
    388         return staticmethod(wrapped)
    389 

OSError: [Errno 39] Directory not empty: 'ab'

In [22]: 
In [23]: f = pathlib.Path('./ab/cd/a.txt')

In [24]: f.exists()
Out[24]: True

In [25]: f.is_file()
Out[25]: True

In [26]: d = pathlib.Path('./ab/cd/d.txt')

In [27]: d.exists()               # 可以用来 判断该路径是否存在!
Out[27]: False

In [28]: d.is_file()
Out[28]: False

In [29]: f.is_absolute()  # 如果是绝对路径 则返回 True

驱动器)。
Out[29]: False

In [30]: d = pathlib.Path('/home/')

In [31]: d.is_absolute()  # 如果是绝对路径 则返回 True
Out[31]: True

In [32]: f.absolute().as_uri() # 将路径返回为 file: URI
Out[32]: 'file:///home/magedu/ab/cd/a.txt'

In [33]: f.cwd()
Out[33]: PosixPath('/home/magedu')

In [34]: f.absolute()
Out[34]: PosixPath('/home/magedu/ab/cd/a.txt')

In [35]: f.expanduser()
Out[35]: PosixPath('ab/cd/a.txt')

In [36]: pathlib.Path('~').expanduser()
Out[36]: PosixPath('/root')

In [37]: f.home()
Out[37]: PosixPath('/root')

In [38]: f.lchmod  # 链接
Out[38]: <bound method Path.lchmod of PosixPath('ab/cd/a.txt')>

In [39]: f.name
Out[39]: 'a.txt'

In [40]: f.home().name()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-40-cdc3e8c3b25b> in <module>()
----> 1 f.home().name()

TypeError: 'str' object is not callable

In [41]: f.home().name
Out[41]: 'root'

In [42]: f.owner()
Out[42]: 'root'

In [43]: f.parent
Out[43]: PosixPath('ab/cd')

In [44]: f.home().parent
Out[44]: PosixPath('/')

In [45]: f.parents
Out[45]: <PosixPath.parents>

In [46]: f.parts
Out[46]: ('ab', 'cd', 'a.txt')

In [47]: f.home().root
Out[47]: '/'

In [48]: f.suffix       # 文档的后缀
Out[48]: '.txt'


In [50]: f.suffixes     # 将文档的后缀放入一个列表中
Out[50]: ['.txt']

In [51]: f.touch        # 如果它不存在,就用指定的访问模式创建这个文件
Out[51]: <bound method Path.touch of PosixPath('ab/cd/a.txt')>

In [52]: 

1、start

In [61]: f.stat()
Out[61]: os.stat_result(st_mode=33188, st_ino=1185203, st_dev=66307, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1510587456, st_mtime=1510587456, st_ctime=1510587456)

In [62]: f.lstat()
Out[62]: os.stat_result(st_mode=33188, st_ino=1185203, st_dev=66307, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1510587456, st_mtime=1510587456, st_ctime=1510587456)

In [63]: 

2、glob

In [64]: f
Out[64]: PosixPath('ab/cd/a.txt')

In [65]: d
Out[65]: PosixPath('/home')

In [66]: d = pathlib.Path('.')

In [67]: d.glob('**/*.py') 
Out[67]: <generator object Path.glob at 0x7f03ad69aba0>

In [68]: for x in d.glob('**/*.py')
  File "<ipython-input-68-2a1a184286ac>", line 1
    for x in d.glob('**/*.py')
                              ^
SyntaxError: invalid syntax


In [69]: for x in d.glob('**/*.py'):
    ...:     print(x)
    ...:     
hello.py
# ... 略


In [70]: help(d.glob)  # 迭代子目录,生成指定类型的文件

Help on method glob in module pathlib:

glob(pattern) method of pathlib.PosixPath instance
    Iterate over this subtree and yield all existing files (of any
    kind, including directories) matching the given pattern.
~
(END)


In [72]: help(d.rglob)  # 递归生成 所有位置上的指定类型的文件。

Help on method rglob in module pathlib:

rglob(pattern) method of pathlib.PosixPath instance
    .
~

(END)


In [69]: for x in d.glob('**/*.py'):
    ...:     print(x)
    ...:     
hello.py
# ... 略


3、join

In [76]: p = '/' + 'miracle' + '/' + 'Project' + '/' + 'workspace'

In [77]: pathlib.Path('/', '/Users', 'miracleYoung', 'Project') 
Out[77]: PosixPath('/Users/miracleYoung/Project')
# 根据系统环境以及给出的内容,生成 str形式的 路径。可以修正输入的错误
In [78]: 

4、copy

In [81]: import shutil        # 权限,id,uid, gid

In [82]: shutil.copyfileobj   # 文件对象
Out[82]: <function shutil.copyfileobj>

In [83]: shutil.copyfile      # 文件内容
Out[83]: <function shutil.copyfile>

In [84]: shutil.copymode      # 权限
Out[84]: <function shutil.copymode>

In [85]: shutil.copystat      # 元数据
Out[85]: <function shutil.copystat>

In [86]: shutil.copy          # copyfile + copymode
Out[86]: <function shutil.copy>

In [87]: shutil.copy2         # copyfile + copystat
Out[87]: <function shutil.copy2>

In [88]: shutil.copytree      # 递归复制
Out[88]: <function shutil.copytree>

In [89]: 

5、remove

In [90]: shutil.rmtree    # remove tree; 递归删除目录树
Out[90]: <function shutil.rmtree>

In [91]: help(shutil.rmtree)

Help on function rmtree in module shutil:

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 platform and implementation dependent;
    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.

~
(END)

In [92]: shutil.move     # 递归地将文件或目录移到另一个位置。这是类似于UNIX“mv”命令。返回文件或目录的目的地
Out[92]: <function shutil.move>

In [93]: help(shutil.move)

Help on function move in module shutil:

move(src, dst, copy_function=<function copy2 at 0x7f03b65a90d0>)
    Recursively move a file or directory to another location. This is
    similar to the Unix "mv" command. Return the file or directory's
    destination.  

    
    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. Symlinks are
    recreated under the new name if os.rename() fails because of cross
    filesystem renames.
    
    The optional `copy_function` argument is a callable that will be used
    to copy the source or it will be delegated to `copytree`.
    By default, copy2() is used, but any function that supports the same
    signature (like copy()) can be used.
    
    A lot more could be done here...  A look at a mv.c shows a lot of
    the issues this implementation glosses over.

~
(END)

三、序列化与反序列化

  • 序列化: 将对象转化为数据
  • 反序列化: 将数据转化为对象

1、pickle模块

In [95]: import pickle

In [96]: class A:
    ...:     def pr(self):
    ...:         print('xxx')
    ...:         

In [97]: a = A()

In [98]: b = pickle.dumps(a)            # dumps(object) -> string

In [99]: aa = pickle.loads(b)           # loads(string) -> object 

In [100]: a
Out[100]: <__main__.A at 0x7f03ad617b38>

In [101]: a.pr()
xxx

In [102]: aa.pr
Out[102]: <bound method A.pr of <__main__.A object at 0x7f03ac095438>>

In [103]: aa.pr()
xxx

In [104]: b
Out[104]: b'\x80\x03c__main__\nA\nq\x00)\x81q\x01.'

In [105]: 
In [107]: obj = list(range(10))

In [108]: obj
Out[108]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [109]: pickle.dumps(obj)
Out[109]: b'\x80\x03]q\x00(K\x00K\x01K\x02K\x03K\x04K\x05K\x06K\x07K\x08K\te.'

In [110]: class RPC:
     ...:     def __init__(self):
     ...:         self.date = []
     ...:     def server(self):
     ...:         self.date = list(range(10))
     ...:     def client(self):
     ...:         print(self.date) 
     ...:                

In [111]: s = RPC()

In [112]: s.server()

In [113]: s.date
Out[113]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [114]: pickle.dumps(s)
Out[114]: b'\x80\x03c__main__\nRPC\nq\x00)\x81q\x01}q\x02X\x04\x00\x00\x00dateq\x03]q\x04(K\x00K\x01K\x02K\x03K\x04K\x05K\x06K\x07K\x08K\tesb.'

In [115]: 

2、json

In [116]: import json

  • object
  • array
  • number
  • string
  • bool
  • null
  • dict
  • list
  • int/float
  • str
  • bool
  • None
In [118]: d = {'a': 1, 'b': [1, 2, 3]}

In [119]: s = json.dumps(d)

In [120]: type(s)
Out[120]: str

In [121]: json.loads(s)
Out[121]: {'a': 1, 'b': [1, 2, 3]}

In [122]: 

第六周作业

  1. 实现ls 命令,至少实现 -l -a -h 选项
  2. 实现find 命令 至少实现 -name -type -ctime -mtime
  3. 实现cp 命令,至少实现 -r -p 选项

python ls.py = ls

python ls.py -l = ls -l

转载于:https://my.oschina.net/u/3552459/blog/1572891

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值