嗯,那如何要把游標的位置給打印來?

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('test', 'r')
print(f.tell())---------------執行結果---------------0Process finished with exit code 0

那在試試把文件讀完後,再打印一次游標位置

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('test', 'r')
print(f.tell())
print(f.readline())
print(f.tell())---------------執行結果---------------
0
Python(英國發音:/ˈpaɪθən/ 美國發音:/ˈpaɪθɑːn/),是一種物件導向、直譯式的電腦程式語言129   # 129個字符,記得換行符號要也算進去哦Process finished with exit code 0

唔…不相信?是129個字符,好吧,那就用另一個方式read()來呈現好了,預設read()不指定的話,是讀取所有的,因此我們這次使用read(6)來試試,看看是不是真的為6個字符

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('test', 'r')
print(f.tell())
print(f.read(6))
print(f.tell())---------------執行結果---------------0
Python
6Process finished with exit code 0

嗯嗯,真的是6個字符,那通常我們還是會用readline(),因為這樣不用去數這一行有幾個字符,直接幫你讀取整行,那假設我們現在讀取了三行後,要怎麼讓游標回到一開始?

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('test', 'r')
print(f.tell())
print(f.readline())
print(f.readline())
print(f.readline())
print(f.tell())
f.seek(0)
print(f.readline())---------------執行結果---------------0
Python(英國發音:/ˈpaɪθən/ 美國發音:/ˈpaɪθɑːn/),是一種物件導向、直譯式的電腦程式語言它包含了一組功能完備的標準庫,能夠輕鬆完成很多常見的任務。它的語法簡單,與其它大多數程式設計語言使用大括弧不一樣,它使用縮進來定義語句塊與Scheme、Ruby、Perl、Tcl等動態語言一樣,Python具備垃圾回收功能,能夠自動管理記憶體使用454
Python(英國發音:/ˈpaɪθən/ 美國發音:/ˈpaɪθɑːn/),是一種物件導向、直譯式的電腦程式語言Process finished with exit code 0

唔…觀察一下,游標真的回到一開始了,原來使用seek(0)就可以了,通常tell()會跟seek()一起使用,tell()會打印出目前游標的位置,seek()可以指定游標的位置停在哪裡

那如果要檢查文件是用什麼字符編碼的,要怎麼查呢?

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('test', 'r')
print(f.readline())
print(f.encoding)---------------執行結果---------------Python(英國發音:/ˈpaɪθən/ 美國發音:/ˈpaɪθɑːn/),是一種物件導向、直譯式的電腦程式語言UTF-8Process finished with exit code 0

唔,看到打印出UTF-8了,這樣就可以確定了

觀察一下,下面代碼的fileno()name()

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open("test", "wb")
print ("Name of the file: ", f.name)fid = f.fileno()
print ("File Descriptor: ", fid)---------------執行結果---------------Name of the file:  foo.txt
File Descriptor:  3

fileno() 這個是作業系統專門的接口,專門去調度系统的 I/O 操作,這個接口是提供給所有程式語言使用,並不是Python才會有的

name() 這個是打印出文件名字,很簡單吧

isatty() 就是判斷是不是一個終端設備,為真返回True,這個較少用

seekable() 不是所有的文件都可以移動游標,這個主要是拿來判斷普通文件裡的游標能不能移動,為真返回True

readable() 判斷文件是不是可讀的權限,為真返回True

writable() 判斷文件是不是可寫的權限,為真返回True

flush() 即時地把記憶體中的緩衝區裡的資料,立刻寫回至文件中,同時清空緩衝區,一般情況下,文件關閉後會自動刷新緩衝區,但有時你需要在關閉前刷新它,這時就可以使用 flush()方法

下面我們來做一下實驗,先在terminal開二個分頁,一個用python3執行,進行互動模式,另一個用tail -f foo.txt 即時地去監看這個文件的變化,當我在分頁一執行flush()時,看看分頁二裡的文件是不是即時地被寫入

唔…看起來flush()的使用情境就是上圖的用法

接下來做一個比較有趣的應用,來實做一個進度條

#!/usr/bin/env python3
# -*- coding:utf-8 -*-import sys, timefor i in range(20):sys.stdout.write("#")sys.stdout.flush()time.sleep(0.5)

這個代碼,各位可以試試看,挺有趣的應用…

closed 判斷文件是不是關閉,為真返回True

再來講一下 truncate(),這個是截斷字符串用的

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'a', encoding='utf-8')
f.truncate()---------------執行結果---------------Hello Python
Hello Python1
Hello Python2
Hello Python3
Hello Python4

打開文件的模式改成用a,發現並不會去截斷字符串,那如果改成truncate(4),看看會有什麼不同?

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'a', encoding='utf-8')
f.truncate(4)---------------執行結果---------------Hell

觀察發現,怎麼字符串從第四個之後被截斷了,這是因為truncate(4)的關係,那我們在加入先前學到的seek(),能不能從特定指定的位置之後開始截斷字符串,那要怎麼做呢?


#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'a', encoding='utf-8')
f.seek(10)
f.truncate(7)---------------執行結果---------------Hello P

有發現了嗎?怎麼還是一樣是從頭開始截7個字符串,完全沒有依照原本的想像,從指定的第10個字符串開始往後截斷,所以由此可知,truncate()截斷的標準,完全不受seek()影響的

先前示範的代碼都只能讀只能寫,接下來我們讓讀寫同時在一起好了,也順便觀察一下,有什麼不一樣的地方

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'r+', encoding='utf-8')
print(f.readline())
print(f.readline())
f.write("----------我是分隔線----------")
print(f.readline())---------------執行結果---------------Hello Python
Hello Python1
Hello Python2
Hello Python3
Hello Python4----------我是分隔線----------

咦,奇怪了,怎麼不是在第二行寫入----------我是分隔線----------,怎麼跑到最後一行了?等於其實因為是r+這個關係,是用讀取跟寫入的方式打開文件,不相信?好吧,那我們就來打印一下游標位置,確認一下是怎麼運作

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'r+', encoding='utf-8')
print(f.readline())
print(f.readline())
print(f.tell())
f.write("----------我是分隔線----------")
print(f.readline())---------------執行結果---------------Hello PythonHello Python127
Hello Python2Process finished with exit code 0觀察文件內容:
Hello Python
Hello Python1
Hello Python2
Hello Python3
Hello Python4----------我是分隔線--------------------我是分隔線----------

觀察一下,上面的代碼,的確真的是以讀寫的方法打開文件了,那剛剛使用r+,那換使用w+,觀察一下,跟r+有什麼不同?

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'w+', encoding='utf-8')
print(f.readline())
print(f.readline())
print(f.tell())
f.write("----------我是分隔線----------")
print(f.readline())---------------執行結果---------------0Process finished with exit code 0觀察文件內容:
----------我是分隔線----------

唔!!!怎麼只剩一行----------我是分隔線----------?這是因為f = open('foo.txt', 'w+', encoding='utf-8')這一句的關係,先打開一個文件叫foo.txt,接著因為w會有truncate的作用,所以不管原本文件裡面有什麼,都會被清空,然後在用寫入至文件裡面,所以上面的代碼執行完畢後,才會只剩下一行,又不相信?好吧,那就再來實驗一下,確認一下到底是怎麼運作的…

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'w+', encoding='utf-8')
print("目前游標起始位置:", f.tell())
f.write("----------我是第一行----------\n")
f.write("----------我是第二行----------\n")
f.write("----------我是第三行----------\n")
f.write("----------我是第四行----------\n")
f.write("----------我是第五行----------\n")
print("目前游標位置:", f.tell())
f.seek(10)
print("游標返回的位置:", f.tell())
print(f.readline())
f.write("My name is Tony Stark, I'm ironman")
print("最後游標的位置:", f.tell())
f.close()---------------執行結果---------------目前游標起始位置: 0
目前游標位置: 180
游標返回的位置: 10
我是第一行----------最後游標的位置: 214Process finished with exit code 0觀察文件內容:
----------我是第一行----------
----------我是第二行----------
----------我是第三行----------
----------我是第四行----------
----------我是第五行----------
My name is Tony Stark, I'm ironman

咦,正常應該要從我是第一行----------這邊開始寫入的,但就是真的沒辦法寫,因為w+是做寫入更新,所以即使游標返回特定位置,一樣不受影響,只會寫在文件裡的最後一行

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'rb', encoding='utf-8')     # 讀取二進制文件
print(f.readline())
print(f.readline())
print(f.readline())
f.close()---------------執行結果---------------Traceback (most recent call last):File "/Python/project/path/file_operation.py", line 4, in <module>f = open('foo.txt', 'rb', encoding='utf-8')     # 讀取二進制文件
ValueError: binary mode doesn't take an encoding argumentProcess finished with exit code 1

若是讀取二進制文件,就不需要傳encoding編碼的參數給它,否則就會報錯,試試把encoding拿掉看看會有什麼結果?

接下來實做一下怎麼對二進制文件做操作

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'rb')     # 讀取二進制文件
print(f.readline())
print(f.readline())
print(f.readline())
f.close()---------------執行結果---------------b'----------\xe6\x88\x91\xe6\x98\xaf\xe7\xac\xac\xe4\xb8\x80\xe8\xa1\x8c----------\n'
b'----------\xe6\x88\x91\xe6\x98\xaf\xe7\xac\xac\xe4\xba\x8c\xe8\xa1\x8c----------\n'
b'----------\xe6\x88\x91\xe6\x98\xaf\xe7\xac\xac\xe4\xb8\x89\xe8\xa1\x8c----------\n'Process finished with exit code 0

有看到前面多了一個b代表這個是一個bytes-like 這個就是指二進制的文件

  1. 網路傳送,只能用二進制進行傳送
  2. 讀取二進制的文件

那既然有rb,也就有wb,那就來看一下怎麼用?

f = open('foo.txt', 'wb')     # 寫入二進制文件
f.write("Hello Binary\n")
f.close()---------------執行結果---------------Traceback (most recent call last):File "/Python/project/path/file_operation.py", line 4, in <module>f = open('fooo.txt', 'rb')     # 讀取二進制文件
TypeError: a bytes-like object is required, not 'str'Process finished with exit code 1

出現TypeError: a bytes-like object is required, not 'str' 這是說明不能是一個字符串,所以我們要把字符串轉成bytes類型(可以回頭參考一下)

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open('foo.txt', 'wb')     # 寫入二進制文件
f.write("Hello Binary\n".encode())
f.close()---------------執行結果---------------
觀察文件內容:Hello Binary

咦!奇怪,為什麼看到的還是一個字符串?其實存的時候不是以0101儲存的,而是文件以二進制編碼儲存

知識點:

U 表示在讀取時,會將\r\n\r\n自動轉換成\n (與 r 或 r+ 模式使用)

  • rU
  • r+U

b 表示處理二進制文件 (如:FTP上傳ISO檔的文件,Linux可以怱略,但windows處理二進制文件時,需要標注)

修改文件有二種方法,一種是把文件裡的所有資料,都暫時存到記憶體裡,找到要修改的文字,然後再回存至文件裡,就像vim一樣,另一種是rename的方式,也就是建立另一個新的文件,然後修改完原本的文件後,寫入至新文件,那我們就來實做第二種方式

準備好二個文件,一個是foo裡面要有內容,另一個新文件是空的 - foo.bak

foo文件內容如下

柯文哲扮演1位到西門町刺青的Rocker,但因實在太怕痛而刺不下去
而柯文哲還以為是真的要在身上刺青
還說「啊?是真的要刺下去嗎?我還沒跟我老婆報備呢。」

foo.bak文件內容如下

要把『是真的要刺下去嗎』 修改成 『不是真的要刺下去吧』,並寫入至foo.bak那要怎麼做咧?

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open("foo", "r", encoding="utf-8")
f_new = open("foo.bak", "w", encoding="utf-8")for line in f:if "是真的要刺下去嗎" in line:line = line.replace("是真的要刺下去嗎", "不是真的要刺下去吧")f_new.write(line)else:f_new.write(line)
f.close()
f_new.close()
  • f = open("foo", "r", encoding="utf-8") 只用讀取模式找到要修改的字符串
  • f_new = open("foo.bak", "w", encoding="utf-8") 用寫入模式,是把上面找到修改後的字符串寫入至新文件裡
  • if "是真的要刺下去嗎" in line: 先找出要修改的字符串
  • replace()來做修改字符串

可以優化成下面代碼

#!/usr/bin/env python3
# -*- coding:utf-8 -*-f = open("foo.txt", "r", encoding="utf-8")
f_new = open("foo.bak", "w", encoding="utf-8")for line in f:if "是真的要刺下去嗎" in line:line = line.replace("是真的要刺下去嗎", "不是真的要刺下去吧")f_new.write(line)
f.close()
f_new.close()

觀察一下foo.bak文件內容

柯文哲扮演1位到西門町刺青的Rocker,但因實在太怕痛而刺不下去
而柯文哲還以為是真的要在身上刺青
還說「啊?不是真的要刺下去吧?我還沒跟我老婆報備呢。」

嗯!確實已經修改了,但上面的代碼,還是寫的不夠好,因為是寫死的,那如果我想讓用戶自已輸入想要替換的文字,那要怎麼做呢?

請在Terminal中執行 $python3 sed.py 是真的要刺下去嗎 不是真的要刺下去吧

#!/usr/bin/env python3
# -*- coding:utf-8 -*-import sysfind_sys = sys.argv[1]
replace_sys = sys.argv[2]f = open("foo.txt", "r", encoding="utf-8")
f_new = open("foo.bak", "w", encoding="utf-8")for line in f:if find_sys in line:line = line.replace(find_sys, replace_sys)f_new.write(line)
f.close()
f_new.close()

在執行這代碼前,先砍掉foo.bak,確認不存在後,再執行上面的代碼,然後觀察一下是不是真的有替換了

那之前在操作文件時,有沒有發現常常有的代碼會寫f.close(),有的沒有寫,其實這是在操作文件時很容易被忽略,所以現在要介紹一個好物,with語句,它會主動幫我們關閉文件,並釋放文件資源,所以可以寫成下面的代碼,就不需要在額外寫f.close()了,這樣就輕鬆一點了

with opne("file.txt", "r", encoding="utf-8") as f:...

所以上面的代碼還可以再優化

#!/usr/bin/env python3
# -*- coding:utf-8 -*-import sysfind_sys = sys.argv[1]
replace_sys = sys.argv[2]with open("foo.txt", "r", encoding="utf-8") as f, \open("foo.bak", "w", encoding="utf-8") as f_new:for line in f:if find_sys in line:line = line.replace(find_sys, replace_sys)f_new.write(line)

同樣在terminal執行上面的代碼

參考資料:

  • fileno

转载于:https://www.cnblogs.com/zarr12steven/p/6209668.html

Python 基礎 - 文件操作_v2相关推荐

  1. 從turtle海龜動畫 學習 Python - 高中彈性課程系列 3 烏龜繪圖 所需之Python基礎

    "Talk is cheap. Show me the code." ― Linus Torvalds 老子第41章 上德若谷 大白若辱 大方無隅 大器晚成 大音希聲 大象無形 道 ...

  2. python 对 yaml 文件操作

    python 对 yaml 文件操作 #!/usr/bin/env python # -*- encoding: utf-8 -*- """ @Introduce : p ...

  3. Python实现tab文件操作

    Python实现tab文件操作 # -*- coding:gbk -*- import os class TABFILE:     def __init__(self, filename, dest_ ...

  4. python怎么读取文件-python怎么读写文件操作

    本节内容:I/O操作概述 文件读写实现原理与操作步骤 文件打开模式 Python文件操作步骤示例 Python文件读取相关方法 文件读写与字符编码 一.I/O操作概述 I/O在计算机中是指Input/ ...

  5. python处理excel教程实例-python 读写excel文件操作示例【附源码下载】

    本文实例讲述了python 读写excel文件操作.分享给大家供大家参考,具体如下: 对excel文件的操作,python有第三方的工具包支持,xlutils,在这个工具包中包含了xlrd,xlwt等 ...

  6. Python中的文件操作和异常

    Python中的文件操作和异常 文章目录 Python中的文件操作和异常 一.文件 01. 文件的概念 1.1 文件的概念和作用 1.2 文件的存储方式 文本文件和二进制文件 02. 文件的基本操作 ...

  7. Python os模块文件操作(二)

    Python os模块文件操作(二) os模块对文件夹和文件的操作很多.可以先看: https://blog.csdn.net/weixin_43790276/article/details/9867 ...

  8. Python os模块文件操作(一)

    Python os模块文件操作(一) 一.文件描述符 在使用代码对文件进行操作时,为了指定操作的文件,避免不了要使用文件描述符,所以我们先介绍什么是文件描述符. 操作系统为了高效管理已经被打开的文件, ...

  9. python怎么读写文件-python怎么读写文件操作

    本节内容:I/O操作概述 文件读写实现原理与操作步骤 文件打开模式 Python文件操作步骤示例 Python文件读取相关方法 文件读写与字符编码 一.I/O操作概述 I/O在计算机中是指Input/ ...

最新文章

  1. 如何防止SSH会话断开连接
  2. FFMPEG结构体分析之AVFormatContext
  3. PHP vs Node.js vs Nginx-Lua(转)
  4. 在c语言中load,一道题理清Objective-C中的load和initialize
  5. [JLOI2014]松鼠的新家
  6. 将视图转为image_使用视图绑定替代 findViewById
  7. PyTorch 入坑六 数据处理模块Dataloader、Dataset、Transforms
  8. 程序员招聘面试那些奇葩 | 文末附高薪内推
  9. Windows上更换鼠标指针图标
  10. QQ,MSN,旺旺在线客服代码
  11. Nebula Graph 系列(1) —— 初识 Nebula
  12. 来自资深会员管理人的深度思考
  13. c语言double型小数点后几位_double类型的数据在输出的时候,C语言编译器对小数部分可以精确到小数点后面的第几位?...
  14. Infrared and Visible Image Fusion using a Deep Learning Framework解析
  15. 04UE4 C++ 入门【力和扭矩】
  16. Fastadmin一键生成菜单栏目
  17. C++题目分享之冰雹猜想
  18. Ambari+HDP+HDP-UTILS下载地址大全
  19. 芯科技之AD7656介绍
  20. delegate、传值、跳转页面

热门文章

  1. 5.1 基于分支定界算法的单机调度
  2. 在安卓开发中,使用腾讯地图实现定位与导航功能
  3. 网络银行转帐落到后台的交易有哪些
  4. Hadoop重点难点:Shuffle过程中的环形缓冲区
  5. PMP第6章知识点回顾,练习题
  6. grunt 使用教程及步骤
  7. seo必备网站分析工具,关键词百度搜索结果查询导出源码
  8. powershell 编程_如何使用PowerShell以编程方式更改Visual Studio中的默认浏览器,并可能使自己陷入困境...
  9. 购买域名和虚拟空间对于建站的必要性
  10. ESP8266学习之路一——WiFi STA