<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      翻譯:《實用的Python編程》09_01_Packages

      目錄| 上一節 (8.3 調試) | 下一節 (9.2 第三方包)

      9.1 包

      如果編寫一個較大的程序,我們并不真的想在頂層將其組織為一個個獨立文件的大型集合。本節對包(package)進行介紹。

      模塊

      任何一個 Python 源文件稱為一個模塊(module)。

      # foo.py
      def grok(a):
          ...
      def spam(b):
          ...
      

      一條 import 語句加載并執行 一個模塊。

      # program.py
      import foo
      
      a = foo.grok(2)
      b = foo.spam('Hello')
      ...
      

      包 vs 模塊

      對于較大的代碼集合,通常將模塊組織到包中。

      # From this
      pcost.py
      report.py
      fileparse.py
      
      # To this
      porty/
          __init__.py
          pcost.py
          report.py
          fileparse.py
      

      首先,選擇一個名字并用該名字創建頂級目錄。如上述的 porty (顯然,第一步最重要的是選擇名字)。

      接著,添加 __init__.py 文件到該目錄中。__init__.py 文件可以是一個空文件。

      最后,把源文件放到該目錄中。

      使用包

      包用作導入的命名空間。

      這意味著現在有了多級導入。

      import porty.report
      port = porty.report.read_portfolio('port.csv')
      

      導入語句還有其它變體:

      from porty import report
      port = report.read_portfolio('portfolio.csv')
      
      from porty.report import read_portfolio
      port = read_portfolio('portfolio.csv')
      

      兩個問題

      這種方法存在兩個主要的問題:

      • 同一包內不同文件之間的導入無效。
      • 包中的主腳本無效。

      因此,基本上一切導入都是無效的,但是,除此之外,程序還是可以工作的。

      問題:導入

      現在,在導入的時候,同一包內的不同文件之間的導入必須包含包名。請記住這個結構:

      porty/
          __init__.py
          pcost.py
          report.py
          fileparse.py
      

      根據上述規則(同一包內的不同文件之間的導入必須包含包名)修改后的導入示例:

      # report.py
      from porty import fileparse
      
      def read_portfolio(filename):
          return fileparse.parse_csv(...)
      

      所有的導入都是絕對的,而不是相對的。

      # report.py
      import fileparse    # BREAKS. fileparse not found
      
      ...
      

      相對導入

      除了使用包名直接導入,還可以使用使用 . 引用當前的包。

      # report.py
      from . import fileparse
      
      def read_portfolio(filename):
          return fileparse.parse_csv(...)
      

      語法:

      from . import modname
      

      使用上述語法使得重命名包變得容易。

      問題:主腳本

      將包內的子模塊作為主腳本運行會導致程序中斷:

      bash $ python porty/pcost.py # BREAKS
      ...
      

      原因:你正在運行單個腳本,而 Python 不知道包的其余部分(sys.path 是錯誤的)。

      所有的導入都會中斷。要想解決這個問題,需要以不同的方式運行程序,可以使用 -m 選項。

      bash $ python -m porty.pcost # WORKS
      ...
      

      __init__.py 文件

      該文件的主要目的是將模塊組織在一起。

      例如:

      # porty/__init__.py
      from .pcost import portfolio_cost
      from .report import portfolio_report
      

      這使得導入的時候名字出現在頂層。

      from porty import portfolio_cost
      portfolio_cost('portfolio.csv')
      

      而不是使用多級導入:

      from porty import pcost
      pcost.portfolio_cost('portfolio.csv')
      

      腳本的另一種解決方案

      如前所述,需要使用 -m package.module 運行包內的腳本。

      bash % python3 -m porty.pcost portfolio.csv
      

      還有另一種選擇:編寫一個新的頂級腳本。

      #!/usr/bin/env python3
      # pcost.py
      import porty.pcost
      import sys
      porty.pcost.main(sys.argv)
      

      腳本位于包外面。目錄結構如下:

      pcost.py       # top-level-script
      porty/         # package directory
          __init__.py
          pcost.py
          ...
      

      應用結構

      代碼組織和文件結構是應用程序可維護性的關鍵。

      對于 Python 而言,沒有“放之四海而皆準”的方法,但是一個適用于多種問題的結構就是這樣:

      porty-app/
        README.txt
        script.py         # SCRIPT
        porty/
          # LIBRARY CODE
          __init__.py
          pcost.py
          report.py
          fileparse.py
      

      頂級 porty-app 目錄是所有其他內容的容器——這些內容包括文檔,頂級腳本,用例等。

      同樣,頂級腳本(如果有)需要放置在代碼包之外(包的上一層)。

      #!/usr/bin/env python3
      # porty-app/script.py
      import sys
      import porty
      
      porty.report.main(sys.argv)
      

      練習

      此時,我們有了一個包含多個程序的目錄:

      pcost.py          # computes portfolio cost
      report.py         # Makes a report
      ticker.py         # Produce a real-time stock ticker
      

      同時,還有許多具有各種功能的支持模塊:

      stock.py          # Stock class
      portfolio.py      # Portfolio class
      fileparse.py      # CSV parsing
      tableformat.py    # Formatted tables
      follow.py         # Follow a log file
      typedproperty.py  # Typed class properties
      

      在本次練習中,我們將整理這些代碼并將它們放入一個通用包中。

      練習 9.1:創建一個簡單的包

      請創建一個名為 porty 的目錄并將上述所有的 Python 文件放入其中。另外,在 porty 目錄中創建一個空的 __init__.py 文件。最后,文件目錄看起來像這樣:

      porty/
          __init__.py
          fileparse.py
          follow.py
          pcost.py
          portfolio.py
          report.py
          stock.py
          tableformat.py
          ticker.py
          typedproperty.py
      

      請將 porty 目錄中的 __pycache__ 目錄移除。該目錄包含了之前預編譯的 Python 模塊。我們想重新開始。

      嘗試導入包中的幾個模塊:

      >>> import porty.report
      >>> import porty.pcost
      >>> import porty.ticker
      

      如果這些導入失敗,請進入到合適的文件中解決模塊導入問題,使其能夠包括相對導入。例如,import fileparse 語句可以像下面這樣進行修改:

      # report.py
      from . import fileparse
      ...
      

      如果有類似于 from fileparse import parse_csv 這樣的語句,請像下面這樣修改代碼:

      # report.py
      from .fileparse import parse_csv
      ...
      

      練習 9.2:創建應用目錄

      對應用而言,將所有代碼放到“包”中通常是不夠的。有時,支持文件,文檔,腳本等文件需要放到 porty/ 目錄之外。

      請創建一個名為 porty-app 的新目錄。然后將我們在練習 9.1 中創建的 porty 目錄移動到 porty-app 目錄中。接著,復制測試文件 Data/portfolio.csvData/prices.csvporty-app 目錄。另外,在 porty-app 目錄下創建一個 README.txt 文件,該文件包含一些有關自己的信息。現在,代碼的組織結構像下面這樣:

      porty-app/
          portfolio.csv
          prices.csv
          README.txt
          porty/
              __init__.py
              fileparse.py
              follow.py
              pcost.py
              portfolio.py
              report.py
              stock.py
              tableformat.py
              ticker.py
              typedproperty.py
      

      要運行代碼,需要確保你現在正在頂級目錄 porty-app/ 下。例如,從終端運行:

      shell % cd porty-app
      shell % python3
      >>> import porty.report
      >>>
      

      嘗試將之前的腳本作為主程序運行:

      shell % cd porty-app
      shell % python3 -m porty.report portfolio.csv prices.csv txt
            Name     Shares      Price     Change
      ---------- ---------- ---------- ----------
              AA        100       9.22     -22.98
             IBM         50     106.28      15.18
             CAT        150      35.46     -47.98
            MSFT        200      20.89     -30.34
              GE         95      13.48     -26.89
            MSFT         50      20.89     -44.21
             IBM        100     106.28      35.84
      
      shell %
      

      練習 9.3:頂級腳本

      使用 python -m 命令通常有點怪異。可能需要編寫一個頂級腳本來處理奇怪的包。請創建一個生成上述報告的腳本 print-report.py

      #!/usr/bin/env python3
      # print-report.py
      import sys
      from porty.report import main
      main(sys.argv)
      

      然后把腳本 print-report.py 放到頂級目錄 porty-app/ 中。并確保可以在 porty-app/ 目錄下運行它:

      shell % cd porty-app
      shell % python3 print-report.py portfolio.csv prices.csv txt
            Name     Shares      Price     Change
      ---------- ---------- ---------- ----------
              AA        100       9.22     -22.98
             IBM         50     106.28      15.18
             CAT        150      35.46     -47.98
            MSFT        200      20.89     -30.34
              GE         95      13.48     -26.89
            MSFT         50      20.89     -44.21
             IBM        100     106.28      35.84
      
      shell %
      

      最后,代碼的組織結構應該下面這樣:

      porty-app/
          portfolio.csv
          prices.csv
          print-report.py
          README.txt
          porty/
              __init__.py
              fileparse.py
              follow.py
              pcost.py
              portfolio.py
              report.py
              stock.py
              tableformat.py
              ticker.py
              typedproperty.py
      

      目錄| 上一節 (8.3 調試) | 下一節 (9.2 第三方包)

      注:完整翻譯見 https://github.com/codists/practical-python-zh

      posted @ 2021-04-16 16:43  codists  閱讀(340)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国99久9在线 | 免费| 亚洲日韩一区精品射精| 办公室强奷漂亮少妇同事| 日本一区二区精品色超碰| 国产精品制服丝袜第一页| 国产成人精品无码免费看| 成年女人免费v片| 成人aⅴ综合视频国产| 久久亚洲精品中文字幕无| 国产免费久久精品44| 日韩欧美在线综合网另类| 亚洲av中文久久精品国内| 精品国产免费人成在线观看| 国产精品成人午夜福利| 日本亚洲色大成网站www久久| 无码人妻丰满熟妇区五十路在线| 天堂网在线.www天堂在线资源| 激情综合网五月婷婷| 九九久久人妻一区精品色| 亚洲另类无码一区二区三区| 日韩有码精品中文字幕| 丰满人妻被黑人猛烈进入| 欧美不卡无线在线一二三区观| 国产成熟女人性满足视频| 欧美乱码卡一卡二卡四卡免费| 欧美一区二区三区欧美日韩亚洲| 蜜臀av无码一区二区三区| 亚洲精品日韩中文字幕| 亚洲国产精品成人一区二区在线| 中文字幕少妇人妻精品| 亚洲国产成人久久77| 四虎影视国产精品永久在线| 苍南县| 人人妻碰人人免费| 福利视频在线一区二区| 97人人模人人爽人人喊网| 99麻豆久久精品一区二区| 日韩一区在线中文字幕| 欧美成人精精品一区二区三区| 国产色悠悠视频在线观看| 中文字幕亚洲人妻系列|