<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          求求你,別用 os.path 了

          共 9976字,需瀏覽 20分鐘

           ·

          2021-05-27 19:31

          ↑↑↑關(guān)注后"星標"簡說Python

          人人都可以簡單入門Python、爬蟲、數(shù)據(jù)分析
           簡說Python推薦 
          來源:Python七號
          作者:somenzz

          大家好,我是老表~

          前段時間,在使用新版本的 Django 時,我發(fā)現(xiàn)了 settings.py 的第一行代碼從

          import os
          BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

          變成了

          from pathlib import Path
          BASE_DIR = Path(__file__).resolve().parent.parent

          于是我就好奇,os 和 pathlib 同樣是標準庫,為什么 pathlib 得到了 Django 的青睞?學(xué)習了一番 pathlib 之后,發(fā)現(xiàn)這是一個非常高效便捷的工具,用它來處理文件系統(tǒng)路徑相關(guān)的操作最合適不過,集成了很多快捷的功能,提升你的編程效率,那是妥妥的。

          接下來讓一起看一下,為什么 pathlib 更值得我們使用。

          pathlib vs os

          話不多說,先看下使用對比:比如說

          1. 打印當前的路徑:

          使用 os:

          In [13]: import os

          In [14]: os.getcwd()
          Out[14]: '/Users/aaron'

          使用 pathlib:

          In [15]: from pathlib import Path

          In [16]: Path.cwd()
          Out[16]: PosixPath('/Users/aaron')
          In [17]: print(Path.cwd())
          /Users/aaron

          使用 print 打印的結(jié)果是一樣的,但 os.getcwd() 返回的是字符串,而 Path.cwd() 返回的是 PosixPath 類,你還可以對此路徑進行后續(xù)的操作,會很方便。

          1. 判斷路徑是否存在:

          使用 os:

          In [18]: os.path.exists("/Users/aaron/tmp")
          Out[18]: True

          使用 pathlib:

          In [21]: tmp = Path("/Users/aaron/tmp")

          In [22]: tmp.exists()
          Out[22]: True

          可以看出 pathlib 更易讀,更面向?qū)ο蟆?/p>

          1. 顯示文件夾的內(nèi)容
          In [38]: os.listdir("/Users/aaron/tmp")
          Out[38]: ['.DS_Store''.hypothesis''b.txt''a.txt''c.py''.ipynb_checkpoints']

          In [39]: tmp.iterdir()
          Out[39]: <generator object Path.iterdir at 0x7fa3f20d95f0>

          In [40]: list(tmp.iterdir())
          Out[40]:
          [PosixPath('/Users/aaron/tmp/.DS_Store'),
           PosixPath('/Users/aaron/tmp/.hypothesis'),
           PosixPath('/Users/aaron/tmp/b.txt'),
           PosixPath('/Users/aaron/tmp/a.txt'),
           PosixPath('/Users/aaron/tmp/c.py'),
           PosixPath('/Users/aaron/tmp/.ipynb_checkpoints')]

          可以看出 Path().iterdir 返回的是一個生成器,這在目錄內(nèi)文件特別多的時候可以大大節(jié)省內(nèi)存,提升效率。

          1. 通配符支持

          os 不支持含有通配符的路徑,但 pathlib 可以:

          In [45]: list(Path("/Users/aaron/tmp").glob("*.txt"))
          Out[45]: [PosixPath('/Users/aaron/tmp/b.txt'), PosixPath('/Users/aaron/tmp/a.txt')]
          1. 便捷的讀寫文件操作

          這是 pathlib 特有的:

          f = Path('test_dir/test.txt'))
          f.write_text('This is a sentence.')
          f.read_text()

          也可以使用 with 語句:

          >>> p = Path('setup.py')
          >>> with p.open() as f: f.readline()
          ...
          '#!/usr/bin/env python3\n'
          1. 獲取文件的元數(shù)據(jù)
          In [56]: p = Path("/Users/aaron/tmp/c.py")

          In [57]: p.stat()
          Out[57]: os.stat_result(st_mode=33188, st_ino=35768389, st_dev=16777221, st_nlink=1, st_uid=501, st_gid=20, st_size=20, st_atime=1620633580, st_mtime=1620633578, st_ctime=1620633578)

          In [58]: p.parts
          Out[58]: ('/''Users''aaron''tmp''c.py')

          In [59]: p.parent
          Out[59]: PosixPath('/Users/aaron/tmp')

          In [60]: p.resolve()
          Out[60]: PosixPath('/Users/aaron/tmp/c.py')

          In [61]: p.exists()
          Out[61]: True

          In [62]: p.is_dir()
          Out[62]: False

          In [63]: p.is_file()
          Out[63]: True

          In [64]: p.owner()
          Out[64]: 'aaron'

          In [65]: p.group()
          Out[65]: 'staff'

          In [66]: p.name
          Out[66]: 'c.py'

          In [67]: p.suffix
          Out[67]: '.py'

          In [68]: p.suffixes
          Out[68]: ['.py']

          In [69]: p.stem
          Out[69]: 'c'

          1. 路徑的連接 join

          相比 os.path.join,使用一個 / 是不是更為直觀和便捷?

          >>> p = PurePosixPath('foo')
          >>> p / 'bar'
          PurePosixPath('foo/bar')
          >>> p / PurePosixPath('bar')
          PurePosixPath('foo/bar')
          >>> 'bar' / p
          PurePosixPath('bar/foo')

          當然,也可以使用 joinpath 方法

          >>> PurePosixPath('/etc').joinpath('passwd')
          PurePosixPath('/etc/passwd')
          >>> PurePosixPath('/etc').joinpath(PurePosixPath('passwd'))
          PurePosixPath('/etc/passwd')
          >>> PurePosixPath('/etc').joinpath('init.d''apache2')
          PurePosixPath('/etc/init.d/apache2')
          >>> PureWindowsPath('c:').joinpath('/Program Files')
          PureWindowsPath('c:/Program Files')
          1. 路徑匹配
          >>> PurePath('a/b.py').match('*.py')
          True
          >>> PurePath('/a/b/c.py').match('b/*.py')
          True
          >>> PurePath('/a/b/c.py').match('a/*.py')
          False

          pathlib 出現(xiàn)的背景和要解決的問題

          pathlib 目的是提供一個簡單的類層次結(jié)構(gòu)來處理文件系統(tǒng)的路徑,同時提供路徑相關(guān)的常見操作。那為什么不使用 os 模塊或者 os.path 來實現(xiàn)呢?

          許多人更喜歡使用 datetime 模塊提供的高級對象來處理日期和時間,而不是使用數(shù)字時間戳和 time 模塊 API。同樣的原因,假如使用專用類表示文件系統(tǒng)路徑,也會更受歡迎。

          換句話說,os.path 是面向過程風格的,而 pathlib 是面向?qū)ο箫L格的。Python 也在一直在慢慢地從復(fù)制 C 語言的 API 轉(zhuǎn)變?yōu)閲@各種常見功能提供更好,更有用的抽象。

          其他方面,使用專用的類處理特定的需求也是很有必要的,例如 Windows 路徑不區(qū)分大小寫。

          在這樣的背景下,pathlib 在 Python 3.4 版本加入標準庫。

          pathlib 的優(yōu)勢和劣勢分別是什么

          pathlib 的優(yōu)勢在于考慮了 Windows 路徑的特殊性,同時提供了帶 I/O 操作的和不帶 I/O 操作的類,使用場景更加明確,API 調(diào)用更加易懂。

          先看下 pathlib 對類的劃分:

          圖中的箭頭表示繼承自,比如 Path 繼承自 PurePath,PurePath 表示純路徑類,只提供路徑常見的操作,但不包括實際 I/O 操作,相對安全;Path 包含 PurePath 的全部功能,包括 I/O 操作。

          PurePath 有兩個子類,一個是 PureWindowsPath,表示 Windows 下的路徑,不區(qū)分大小寫,另一個是 PurePosixPath,表示其他系統(tǒng)的路徑。有了 PureWindowsPath,你可以這樣對路徑進行比較:

          from pathlib import PureWindowsPath
          >>> PureWindowsPath('a') == PureWindowsPath('A')
          True

          PurePath 可以在任何操作系統(tǒng)上實例化,也就是說與平臺無關(guān),你可以在 unix 系統(tǒng)上使用 PureWindowsPath,也可以在 Windows 系統(tǒng)上使用 PurePosixPath,他們還可以相互比較。

          >>> from pathlib import PurePosixPath, PureWindowsPath, PosixPath  
          >>> PurePosixPath('a') == PurePosixPath('b')
          False
          >>> PurePosixPath('a') < PurePosixPath('b')
          True
          >>> PurePosixPath('a') == PosixPath('a')
          True
          >>> PurePosixPath('a') == PureWindowsPath('a')
          False

          可以看出,同一個類可以相互比較,不同的類比較的結(jié)果是 False。

          相反,包含 I/O 操作的類 PosixPath 及 WindowsPath 只能在對應(yīng)的平臺實例化:

          In [8]: from pathlib import PosixPath,WindowsPath

          In [9]: PosixPath('a')
          Out[9]: PosixPath('a')

          In [10]: WindowsPath('a')
          ---------------------------------------------------------------------------
          NotImplementedError                       Traceback (most recent call last)
          <ipython-input-10-cc7a0d86d4ed> in <module>
          ----> 1 WindowsPath('a')

          /Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/pathlib.py in __new__(cls, *args, **kwargs)
             1038         self = cls._from_parts(args, init=False)
             1039         if not self._flavour.is_supported:
          -> 1040             raise NotImplementedError("cannot instantiate %r on your system"
             1041                                       % (cls.__name__,))
             1042         self._init()

          NotImplementedError: cannot instantiate 'WindowsPath' on your system

          In [11]:

          要說劣勢,如果有的話,那就是在選擇類時會比較困惑,到底用哪一個呢?其實如果你不太確定的話,用 Path 就可以了,這也是它的名稱最短的原因,因為更加常用,短點的名稱編寫的更快。

          適用的場景

          如果要處理文件系統(tǒng)相關(guān)的操作,選 pathlib 就對了。

          一些關(guān)鍵點

          獲取家目錄:

          In [70]: from pathlib import Path

          In [71]: Path.home()
          Out[71]: PosixPath('/Users/aaron')

          父目錄的層級獲取:

          >>> p = PureWindowsPath('c:/foo/bar/setup.py')
          >>> p.parents[0]
          PureWindowsPath('c:/foo/bar')
          >>> p.parents[1]
          PureWindowsPath('c:/foo')
          >>> p.parents[2]
          PureWindowsPath('c:/')

          獲取多個文件后綴:

          >>> PurePosixPath('my/library.tar.gar').suffixes
          ['.tar''.gar']
          >>> PurePosixPath('my/library.tar.gz').suffixes
          ['.tar''.gz']
          >>> PurePosixPath('my/library').suffixes
          []


          Windows 風格轉(zhuǎn) Posix:

          >>> p = PureWindowsPath('c:\\windows')
          >>> str(p)
          'c:\\windows'
          >>> p.as_posix()
          'c:/windows'

          獲取文件的 uri:

          >>> p = PurePosixPath('/etc/passwd')
          >>> p.as_uri()
          'file:///etc/passwd'
          >>> p = PureWindowsPath('c:/Windows')
          >>> p.as_uri()
          'file:///c:/Windows'

          判斷是否絕對路徑:

          >>> PurePosixPath('/a/b').is_absolute()
          True
          >>> PurePosixPath('a/b').is_absolute()
          False

          >>> PureWindowsPath('c:/a/b').is_absolute()
          True
          >>> PureWindowsPath('/a/b').is_absolute()
          False
          >>> PureWindowsPath('c:').is_absolute()
          False
          >>> PureWindowsPath('//some/share').is_absolute()
          True

          文件名若有變化:

          >>> p = PureWindowsPath('c:/Downloads/pathlib.tar.gz')
          >>> p.with_name('setup.py')
          PureWindowsPath('c:/Downloads/setup.py')

          是不是非常方便?

          技術(shù)的底層原理和關(guān)鍵實現(xiàn)

          pathlib 并不是基于 str 的實現(xiàn),而是基于 object 設(shè)計的,這樣就嚴格地區(qū)分了 Path 對象和字符串對象,同時也用到了一點 os 的功能,比如 os.name,os.getcwd 等,這一點大家可以看 pathlib 的源碼了解更多。

          最后的話

          本文分享了 pathlib 的用法,后面要處理路徑相關(guān)的操作時,你應(yīng)該第一時間想到 pathlib,不會用沒有關(guān)系,搜索引擎所搜索 pathlib 就可以看到具體的使用方法。

          雖然 pathlib 比 os 庫更高級,更方便并且提供了很多便捷的功能,但是我們?nèi)匀恍枰廊绾问褂?os 庫,因為 os 庫是 Python 中功能最強大且最基本的庫之一,但是,在需要一些文件系統(tǒng)操作時,強烈建議使用 pathlib。

          --END--


          留言贈書

          贈書規(guī)則給本文點贊("在看"不作要求),掃描下方二維碼,添加老表的微信。把點贊截圖發(fā)給我,我會發(fā)送抽獎碼給大家,時間截止至05月31號 20:00。抽三位讀者朋友,可獲得《Python Web開發(fā)從入門到精通》贈書一本。

          掃碼即可加我微信

          觀看朋友圈,獲取最新學(xué)習資源

          注意:中獎?wù)?4小時內(nèi),微信私聊我回復(fù):書名+姓名+電話+收件地址即可領(lǐng)取,逾期不候!為了大家都有機會中獎,本月已經(jīng)中過書的朋友,再次中獎將不再贈書。

          本批書籍由 北京大學(xué)出版社 贊助,再次致謝。也歡迎大家自行前往購買支持。

          超級好中間呀~最近幾次都是幾個人抽2-5

          簡說Python 投稿規(guī)則及激勵

          規(guī)則:必須是自己的原創(chuàng)文章,和Python相關(guān)技術(shù)文章,形式不限制(文字、圖文、漫畫等),字數(shù)800+,在微信公眾號首發(fā)。

          激勵

          根據(jù)文章內(nèi)容 字數(shù) 分為兩種基礎(chǔ)和深度

          基礎(chǔ)文章:每投稿兩篇可以獲得技術(shù)相關(guān)圖書一本 從書單里選

          深度文章:每1k字50-100元(代碼不算)

          額外激勵

          文章閱讀量超過2000,激勵50元

          文章被同量級大號轉(zhuǎn)載次數(shù)5次及以上,激勵100元

          長期投稿作者還有額外激勵,技術(shù)能力可以的,還可以一起做項目,接私活,內(nèi)推等。



          學(xué)習更多:
          整理了我開始分享學(xué)習筆記到現(xiàn)在超過250篇優(yōu)質(zhì)文章,涵蓋數(shù)據(jù)分析、爬蟲、機器學(xué)習等方面,別再說不知道該從哪開始,實戰(zhàn)哪里找了

          優(yōu)秀的讀者都知道,“點贊”傳統(tǒng)美德不能丟 

          瀏覽 41
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  99国产在线观看 | 色色网站在线观看 | 久久精品五月天 | 日日模日日 | 黑人黄片 |