本章需要用到以下的模块:

from pathlib import Path
import os

文件和文件路径

文件由文件名和路径组成。Linux以/(forward slash)为根路径,Windows以\(backslash)为根路径。

>>> Path('usr', 'include', 'stdio.h')
PosixPath('usr/include/stdio.h')
>>> str(Path('usr', 'include', 'stdio.h'))
'usr/include/stdio.h'
>>> str(Path('/usr/include', 'stdio.h'))
'/usr/include/stdio.h'

和字符串使用+类似,Path对象也可以用/拼接:

>>> Path('/usr/include') / Path('stdio.h')
PosixPath('/usr/include/stdio.h')
>>> Path('/usr/include') / 'stdio.h'
PosixPath('/usr/include/stdio.h')

使用Path而非字符串拼接的好处在于其可以处理操作系统中路径分隔符\/的问题,因此代码更安全。

当前路径和切换路径使用cwd()chdir(),用户根目录使用home():

>>> os.chdir('/usr/include')
>>> Path.cwd()
PosixPath('/usr/include')
>>> Path.home()
PosixPath('/home/user01')

创建目录有两种方法,第一种是os.makedirs(),类似于命令mkdir -p; 第二种是Path().mkdir,类似于命令mkdir
绝对路径与相对路径概念。
Path对象的is_absolute()方法可判断是否为绝对路径,abspath()方法可返回绝对路径。

>>> os.chdir(Path.home())
>>> os.path.abspath('..')
'/home'
>>> Path.cwd().is_absolute()
True
>>> os.path.isabs(Path.cwd())
True

relpath()方法可计算相对路径,第二个参数是起点,第一个是终点:

>>> os.path.relpath('/usr/include', '/tmp')
'../usr/include'

返回文件路径的一部分:

>>> p = Path('/usr/include/stdio.h')
>>> p.anchor
'/'
>>> p.name
'stdio.h'
>>> p.stem
'stdio'
>>> p.suffix
'.h'
>>> p.drive
''
>>> p.parent
PosixPath('/usr/include')
>>> p.parent.name
'include'
# 返回一系列父目录,知道根目录
>>> p.parents
<PosixPath.parents>
>>> p.parents[0]
PosixPath('/usr/include')
>>> p.parents[1]
PosixPath('/usr')
>>> p.parents[2]
PosixPath('/')
>>> p.parents[3]
Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/usr/lib64/python3.6/pathlib.py", line 594, in __getitem__raise IndexError(idx)
IndexError: 3

意外发现,python交互式shell还支持自动完成,按<Tab>键即可。

>>> p = Path('/usr/include/stdio.h')
>>> p.
p.absolute(         p.exists(           p.is_char_device(   p.iterdir(          p.open(             p.relative_to(      p.samefile(         p.unlink(
p.anchor            p.expanduser(       p.is_dir(           p.joinpath(         p.owner(            p.rename(           p.stat(             p.with_name(
p.as_posix(         p.glob(             p.is_fifo(          p.lchmod(           p.parent            p.replace(          p.stem              p.with_suffix(
p.as_uri(           p.group(            p.is_file(          p.lstat(            p.parents           p.resolve(          p.suffix            p.write_bytes(
p.chmod(            p.home(             p.is_reserved(      p.match(            p.parts             p.rglob(            p.suffixes          p.write_text(
p.cwd(              p.is_absolute(      p.is_socket(        p.mkdir(            p.read_bytes(       p.rmdir(            p.symlink_to(
p.drive             p.is_block_device(  p.is_symlink(       p.name              p.read_text(        p.root              p.touch(

获取路径的目录名和文件名:

>>> os.path.basename('/usr/include/stdio.h')
'stdio.h'
>>> os.path.dirname('/usr/include/stdio.h')
'/usr/include'
>>> os.path.dirname(Path('/usr/include/stdio.h'))
'/usr/include'
## 同时获取两者
>>> os.path.split('/usr/include/stdio.h')
('/usr/include', 'stdio.h')

文件大小和目录内容:

>>> os.path.getsize('/usr/include/stdio.h')
31641
>>> os.listdir('.')
['.mozilla', '.bash_logout', '.bashrc', '.cache', '.dbus', '.config', '.ICEauthority', '.local', '.esd_auth', 'Desktop', 'Downloads', 'Templates', 'Public', 'Documents', 'Music', 'Pictures', 'Videos', '.gnupg', '.ssh', '.bash_history', '.pki', 'python_works', '.python_history', '.bash_profile', '.lesshst', '.vimrc', '.vboxclient-clipboard.pid', '.vboxclient-display.pid', '.vboxclient-seamless.pid', '.vboxclient-draganddrop.pid', '.viminfo', 'pcc_2e', '.gitconfig', '.netrc', 'Automate_the_Boring_Stuff_2e_onlinematerials.zip', 'automate_online-materials', 'customValidate.py', '.idlerc']

glob是globbing的简写,表示文件名扩展,文件名代换的意思,平时在shell中常用到,例如ls *.txt
glob模式详见帮助man n glob,常用的为:

  • *表示所有
  • ?表示单个字符
  • [chars]表示匹配任意单个字符
  • {a,b,...}表示匹配任意子模式
>>> p = Path('./automate_online-materials')
>>> for f in p.glob('*.txt'):
...     print(f)
...
automate_online-materials/dictionary.txt
automate_online-materials/guests.txt
automate_online-materials/automate-linux-requirements.txt
automate_online-materials/automate-mac-requirements.txt
automate_online-materials/automate-win-requirements.txt

假设p为Path对象,假设p是Path对象,检查文件的有效性可以用p.exists(), p.is_file(), p.is_dir()

文件读写流程

文件分为平文本文件和二进制文件。
平文本文件的读写使用p.read_text()和p.write_text()。
假设f是File对象,另一种通用的方法是f.open(), f.read()和f.write()。
read()方法将整个文件读取成一个字符串。readlines()将整个文件读取成一个list,每行为一个元素。

$ cat test.txt
row 1
row 2
row 3
row 4>>> from pathlib import Path
>>> f = open('test.txt')
>>> f.read()
'row 1\nrow 2\nrow 3\nrow 4\n'
>>> f.readlines()
[]
>>> f.close()
>>> f = open('test.txt')
>>> f.readlines()
['row 1\n', 'row 2\n', 'row 3\n', 'row 4\n']
>>> f.close()

打开文件可指定不同的模式,如只读(r),读写(+),追加(a)等。可以以二进制模式(b)或文本模式(t)打开。
可以用fseek指定写的位置。

通过SHELVE模块保存变量

使用shelve模块,可以将变量以二进制方式存入文件。实际上就是把文件当数据库用。
shelve文件类似于字典:

>>> import shelve
>>> shelfFile = shelve.open('mydata')
>>> cats = ['Zophie', 'Pooka', 'Simon']
>>> shelfFile['cats'] = cats
>>> shelfFile.close()
>>>
>>> shelfFile = shelve.open('mydata')
>>> type(shelfFile)
<class 'shelve.DbfilenameShelf'>
>>> shelfFile['cats']
['Zophie', 'Pooka', 'Simon']
>>> shelfFile.close()

在看我自己的一个例子:

>>> import shelve
>>> shelfFile = shelve.open('mydata')
>>> shelfFile['name'] = 'steven'
>>> shelfFile['age'] = 48
>>> shelfFile['friends'] = ['bob', 'grace', 'flora']
>>> shelfFile.close()
>>>
>>> shelfFile = shelve.open('mydata')
>>> shelfFile['friends']
['bob', 'grace', 'flora']
>>> shelfFile['name']
'steven'
>>> shelfFile['age']
48
>>>
>>> shelfFile = shelve.open('mydata')
>>> shelfFile.keys()
KeysView(<shelve.DbfilenameShelf object at 0x7f544baf06a0>)
>>> list(shelfFile.keys())
['age', 'friends', 'name']
>>> list(shelfFile.values())
[48, ['bob', 'grace', 'flora'], 'steven']
>>> list(shelfFile.items())
[('age', 48), ('friends', ['bob', 'grace', 'flora']), ('name', 'steven')]
>>> shelfFile.close()# 以下演示文件更新
>>> shelfFile = shelve.open('mydata')
>>> shelfFile['friends']
['bob', 'grace', 'flora']
>>> shelfFile['friends'] = shelfFile.get('friends') + ['john']
>>> shelfFile.close()
>>> shelfFile = shelve.open('mydata')
>>> shelfFile['friends']
['bob', 'grace', 'flora', 'john']

通过PPRINT.PFORMAT()函数保存变量

前面已经介绍过pprint.pprint(),而pprint.pformat()可以返回字符串而非打印。
利用pprint.pformat()可以生成可以import的文件,也就是python可以识别的格式,见下例:

>>> import pprint
>>> cats = [{'name': 'Zophie', 'desc': 'chubby'}, {'name': 'Pooka', 'desc': 'fluffy'}]
>>> print(cats)
[{'name': 'Zophie', 'desc': 'chubby'}, {'name': 'Pooka', 'desc': 'fluffy'}]
>>> pprint.pprint(cats)
[{'desc': 'chubby', 'name': 'Zophie'}, {'desc': 'fluffy', 'name': 'Pooka'}]
>>> fileObj = open('myCats.py', 'w')
>>> fileObj.write('cats = ' + pprint.pformat(cats) + '\n')
83
>>> fileObj.close()
>>>
>>> import myCats
>>> myCats.cats
[{'desc': 'chubby', 'name': 'Zophie'}, {'desc': 'fluffy', 'name': 'Pooka'}]$ cat myCats.py
cats = [{'desc': 'chubby', 'name': 'Zophie'}, {'desc': 'fluffy', 'name': 'Pooka'}]

不过还是优先推荐shelve,因为只有基础数据类型可以用字符串编码,而shelve可以处理其它数据类型。
可以import倒是启发了我,这有点类似于C语言中的include,这样一些变量初始化就可以放到这个文本文件中。
? 不过我试了一下,文件对象也是可以写和后续import的。 此处存疑!

项目: 生成随机问题答卷文件

最关键的部分在以下示例中:

>>> import random
>>> a=[1,2,3,4]
>>> random.shuffle(a)
>>> a
[4, 1, 3, 2]
>>> random.sample(a, 2)
[4, 1]
>>> random.sample(a, 2)
[1, 3]
>>> random.sample(a, 2)
[4, 3]

这是一个非常实用的例子,班上35学生,为每一个学生生成一份不同的试卷,问题都是一样的,但选择的答案和题目的顺序是不一样的。
问题的顺序不同是通过random.shuffle()实现的。选择中有一个正确答案,另外三个是从剩余的选项中通过random.sample(list, 3)实现的。
然后这4个选择再通过random.shuffle打乱。

项目: 可更新的多剪贴板

就是用文件作为剪贴板缓冲。另外len(sys.argv)表示argc

AUTOMATE THE BORING STUFF WITH PYTHON读书笔记 - 第9章:READING AND WRITING FILES相关推荐

  1. AUTOMATE THE BORING STUFF WITH PYTHON读书笔记 - 第8章:INPUT VALIDATION

    THE PYINPUTPLUS MODULE PyInputPlus 模块可用以检查输入有效性,避免手工编写代码. 这个手工代码的例子中有一段,except后可不指定exception,表示所有的ex ...

  2. AUTOMATE THE BORING STUFF WITH PYTHON读书笔记 - 第10章:ORGANIZING FILES

    SHUTIL 模块 shutil是shell utility的简称,使用此模块需要import shutil. 详见在线文档,在线帮助见help(shutil) >>> shutil ...

  3. AUTOMATE THE BORING STUFF WITH PYTHON读书笔记 - 第2章:FLOW CONTROL

    在流程图中,开始和结束圆角矩形表示,菱形表示流控分支,矩形表示实际操作. 布尔值 布尔值包括两个常数,即True和False. 布尔的命名来源于数学家George Boole. 比较操作符 包括==, ...

  4. AUTOMATE THE BORING STUFF WITH PYTHON读书笔记 - 第6章:MANIPULATING STRINGS

    操作字符串 字符串可以用单引号或双引号包围,建议用单引号. 如果字符串中含单引号或双引号,可以用\转移(escape).例如\\, \', \", \n等. >>> a=' ...

  5. AUTOMATE THE BORING STUFF WITH PYTHON读书笔记 - 第12章:WEB SCRAPING

    Web Scraping是指用程序来下载和处理网络上的内容.Scrap是铲,刮和削的意思. 本章介绍的模块包括webbrowser,requests,bs4和selenium. 项目: 使用WEBBR ...

  6. AUTOMATE THE BORING STUFF WITH PYTHON读书笔记 - 第19章:MANIPULATING IMAGES

    本章介绍Pillow模块,可处理图形文件.安装如下: # pillow安装依赖于JPEG源代码 $ sudo yum install libjpeg-turbo-devel $ pip3 instal ...

  7. Automate the Boring Stuff with Python学习笔记1

    将<Automate the Boring Stuff with Python>的语法部分学完了,开始依葫芦画瓢做第一个项目. #! python3 # pw.py - An insecu ...

  8. Python读书笔记第五章:运算符与表达式

    1.运算符 2.运算符优先级 3.表达式 length = 5 breadth = 2 area = length * breadth print 'Area is', area print 'Per ...

  9. Doing Math with Python读书笔记-第6章:Drawing Geometric Shapes and Fractals

    本章学习利用matplotlib画几何图形和分形(fractal) 使用MATPLOTLIB库PATCHES包画几何图形 回顾之前的画图: plt.plot(...) plt.show() 也可以拆解 ...

最新文章

  1. PAT1036:Boys vs Girls
  2. Packt.Java.9.High.Performance.2017.11
  3. htmlparser解决PKIX path building failed问题的两种方法
  4. xp精简工具_Windows10你也可以精简优化,丝滑般极爽轻松做到,再也不卡了
  5. js中push(),pop(),unshift(),shift()的用法小结
  6. Sharepoint开发之旅(2):SiteDefinition自定义母版页
  7. Gitee 管理UE4项目
  8. VC2012安装Opengl开发环境
  9. 怎么在WORD2016里给文档空白处添加下划线,干货在这里,WORD2016空白处如何添加下划线
  10. 怎么切换双显示屏的左右显示器
  11. java 10.0.2 配置 bcprov-jdk-15
  12. 盘点国内十大免费CDN提供商
  13. 机械设计与计算机技术相关的论文,计算机技术机械制造论文-专业论文.doc 文档全文免费预览...
  14. 如何在日内趋势中交易?
  15. 什么是大数据?带你深度了解大数据
  16. NLTK学习笔记(一)
  17. git 远程仓库操作
  18. MindMaster支持全平台、云储存的思维导图工具
  19. Revit:不过期启动“TR天正建筑 V5.0 2020”方法
  20. 玩转Vue3全家桶开篇词丨如何借助Vue3建构你的前端知识体系?

热门文章

  1. Typora+PicGo-Core实现图片自动上传图床详细说明
  2. python3 requests 12306下单环节
  3. 抽象数据类型与计算机内部表示和实现无关,第七话:抽象数据类型ADT
  4. eSight20安装
  5. 【STM32学习】SysTick定时器(嘀嗒定时器)
  6. C语言之#define用法入门详解
  7. C语言中define的用法
  8. 【每周一本书】之《深度学习核心技术与实践》:“小猿搜题”团队倾力之作
  9. python 利用TPOT进行自动机器学习 建模
  10. 小白的数字电路逻辑设计笔记(一)----绪论