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

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

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

      翻譯:《實(shí)用的Python編程》03_02_More_functions

      目錄 | 上一節(jié) (3.1 腳本) | 下一節(jié) (3.3 錯(cuò)誤檢查)

      3.2 深入函數(shù)

      盡管函數(shù)在早先時(shí)候介紹了,但有關(guān)函數(shù)在更深層次上是如何工作的細(xì)節(jié)卻很少提供。本節(jié)旨在填補(bǔ)這些空白,并討論函數(shù)調(diào)用約定,作用域規(guī)則等問題。

      調(diào)用函數(shù)

      考慮以下函數(shù):

      def read_prices(filename, debug):
          ...
      

      可以使用位置參數(shù)調(diào)用該函數(shù):

      prices = read_prices('prices.csv', True)
      

      或者,可以使用關(guān)鍵字參數(shù)調(diào)用該函數(shù):

      prices = read_prices(filename='prices.csv', debug=True)
      

      默認(rèn)參數(shù)

      有時(shí)候,你希望參數(shù)是可選的,如果是這樣,請(qǐng)?jiān)诤瘮?shù)定義中分配一個(gè)默認(rèn)值。

      def read_prices(filename, debug=False):
          ...
      

      如果分配了默認(rèn)值,則參數(shù)在函數(shù)調(diào)用中是可選的。

      d = read_prices('prices.csv')
      e = read_prices('prices.dat', True)
      

      注意:帶有默認(rèn)值的參數(shù)(譯注:即關(guān)鍵字參數(shù))必須出現(xiàn)在參數(shù)列表的末尾(所有非可選參數(shù)都放在最前面)

      首選關(guān)鍵字參數(shù)作為可選參數(shù)

      比較以下兩種不同的調(diào)用風(fēng)格:

      parse_data(data, False, True) # ?????
      
      parse_data(data, ignore_errors=True)
      parse_data(data, debug=True)
      parse_data(data, debug=True, ignore_errors=True)
      

      在大部分情況下,關(guān)鍵字參數(shù)提高了代碼的簡(jiǎn)潔性——特別是對(duì)于用作標(biāo)志的參數(shù),或者與可選特性相關(guān)的參數(shù)。

      設(shè)計(jì)最佳實(shí)踐

      始終為函數(shù)參數(shù)指定簡(jiǎn)短但有意義的名稱。

      使用函數(shù)的人可能想要使用關(guān)鍵字調(diào)用風(fēng)格。

      d = read_prices('prices.csv', debug=True)
      

      Python 開發(fā)工具將會(huì)在幫助功能或者幫助文檔中顯示這些名稱。

      返回值

      return 語句返回一個(gè)值:

      def square(x):
          return x * x
      

      如果沒有給出返回值或者 return 語句缺失,那么返回 None

      def bar(x):
          statements
          return
      
      a = bar(4)      # a = None
      
      # OR
      def foo(x):
          statements  # No `return`
      
      b = foo(4)      # b = None
      

      多個(gè)返回值

      函數(shù)只能返回一個(gè)值。但是,通過將返回值放到元組中,函數(shù)可以返回多個(gè)值:

      def divide(a,b):
          q = a // b      # Quotient
          r = a % b       # Remainder
          return q, r     # Return a tuple
      

      用例:

      x, y = divide(37,5) # x = 7, y = 2
      
      x = divide(37, 5)   # x = (7, 2)
      

      變量作用域

      程序給變量賦值:

      x = value # Global variable
      
      def foo():
          y = value # Local variable
      

      變量賦值發(fā)生在函數(shù)的內(nèi)部和外部。定義在函數(shù)外部的變量是“全局的”。定義在函數(shù)內(nèi)部的變量是“局部的”。

      局部變量

      在函數(shù)內(nèi)部賦值的變量是私有的。

      def read_portfolio(filename):
          portfolio = []
          for line in open(filename):
              fields = line.split(',')
              s = (fields[0], int(fields[1]), float(fields[2]))
              portfolio.append(s)
          return portfolio
      

      在此示例中,filename, portfolio, line, fieldss 是局部變量。在函數(shù)調(diào)用之后,這些變量將不會(huì)保留或者不可訪問。

      >>> stocks = read_portfolio('portfolio.csv')
      >>> fields
      Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      NameError: name 'fields' is not defined
      >>>
      

      局部變量也不能與其它地方的變量沖突。

      全局變量

      函數(shù)可以自由地訪問定義在同一文件中的全局變量值。

      name = 'Dave'
      
      def greeting():
          print('Hello', name)  # Using `name` global variable
      

      但是,函數(shù)不能修改全局變量:

      name = 'Dave'
      
      def spam():
        name = 'Guido'
      
      spam()
      print(name) # prints 'Dave'
      

      切記:函數(shù)中的所有賦值都是局部的

      修改全局變量

      如果必須修改全局變量,請(qǐng)像下面這樣聲明它:

      name = 'Dave'
      
      def spam():
          global name
          name = 'Guido' # Changes the global name above
      

      全局聲明必須在使用之前出現(xiàn),并且相應(yīng)的變量必須與該函數(shù)處在同一文件中。看上面這個(gè)函數(shù),要知道這是一種糟糕的形式。事實(shí)上,如果可以的話,盡量避免使用 global 。如果需要一個(gè)函數(shù)來修改函數(shù)外部的某種狀態(tài),最好是使用類來代替(稍后詳細(xì)介紹)。

      參數(shù)傳遞

      當(dāng)調(diào)用一個(gè)函數(shù)的時(shí)候,參數(shù)變量的傳遞是引用傳遞。不拷貝值(參見2.7 節(jié))。如果傳遞了可變數(shù)據(jù)類型(如列表,字典),它們可以被原地修改。

      def foo(items):
          items.append(42)    # Modifies the input object
      
      a = [1, 2, 3]
      foo(a)
      print(a)                # [1, 2, 3, 42]
      

      關(guān)鍵點(diǎn):函數(shù)不接收輸入?yún)?shù)的拷貝。

      重新賦值與修改

      確保了解修改值與給變量名重新賦值的細(xì)微差別。

      def foo(items):
          items.append(42)    # Modifies the input object
      
      a = [1, 2, 3]
      foo(a)
      print(a)                # [1, 2, 3, 42]
      
      # VS
      def bar(items):
          items = [4,5,6]    # Changes local `items` variable to point to a different object
      
      b = [1, 2, 3]
      bar(b)
      print(b)                # [1, 2, 3]
      

      提醒:變量賦值永遠(yuǎn)不會(huì)重寫內(nèi)存。名稱只是被綁定到了新的值上面

      練習(xí)

      本組練習(xí)實(shí)現(xiàn)的內(nèi)容可能是本課程最強(qiáng)大的和最難的。有很多步驟,并且過去練習(xí)中的許多概念被一次性整合在一起。雖然最后的題解只有大約 25 行的代碼,但要花點(diǎn)時(shí)間,確保你理解每一個(gè)部分。

      report.py 的中心部分主要用于讀取 CSV 文件。例如,read_portfolio() 函數(shù)讀取包含投資組合數(shù)據(jù)的文件,read_prices() 函數(shù)讀取包含價(jià)格數(shù)據(jù)的文件。在這兩個(gè)函數(shù)中,有很多底層的“精細(xì)的”事以及相似的特性。例如,它們都打開一個(gè)文件并使用 csv 模塊來處理,并且將各種字段轉(zhuǎn)換為新的類型。

      如果真的需要對(duì)大量的文件進(jìn)行解析,可能需要清理其中的一些內(nèi)容使其更通用。這是我們的目標(biāo)。

      通過打開 Work/fileparse.py 文件開始本練習(xí),該文件是我們將要寫代碼的地方。

      練習(xí) 3.3:讀取 CSV 文件

      首先,讓我們僅關(guān)注將 CSV 文件讀入字典列表的問題。在 fileparse.py 中,定義一個(gè)如下所示的函數(shù):

      # fileparse.py
      import csv
      
      def parse_csv(filename):
          '''
          Parse a CSV file into a list of records
          '''
          with open(filename) as f:
              rows = csv.reader(f)
      
              # Read the file headers
              headers = next(rows)
              records = []
              for row in rows:
                  if not row:    # Skip rows with no data
                      continue
                  record = dict(zip(headers, row))
                  records.append(record)
      
          return records
      

      該函數(shù)將 CSV 文件讀入字典列表中,但是隱藏了打開文件,使用 csv 模塊處理,忽略空行等詳細(xì)信息。

      試試看:

      提示: python3 -i fileparse.py.

      >>> portfolio = parse_csv('Data/portfolio.csv')
      >>> portfolio
      [{'price': '32.20', 'name': 'AA', 'shares': '100'}, {'price': '91.10', 'name': 'IBM', 'shares': '50'}, {'price': '83.44', 'name': 'CAT', 'shares': '150'}, {'price': '51.23', 'name': 'MSFT', 'shares': '200'}, {'price': '40.37', 'name': 'GE', 'shares': '95'}, {'price': '65.10', 'name': 'MSFT', 'shares': '50'}, {'price': '70.44', 'name': 'IBM', 'shares': '100'}]
      >>>
      

      這很好,除了不能使用數(shù)據(jù)做任何有用的計(jì)算之外。因?yàn)樗械膬?nèi)容都是用字符串表示。我們將馬上解決此問題,先讓我們繼續(xù)在此基礎(chǔ)上進(jìn)行構(gòu)建。

      練習(xí) 3.4:構(gòu)建列選擇器

      在大部分情況下,你只對(duì) CSV 文件中選定的列感興趣,而不是所有數(shù)據(jù)。修改 parse_csv() 函數(shù),以便讓用戶指定任意的列,如下所示:

      >>> # Read all of the data
      >>> portfolio = parse_csv('Data/portfolio.csv')
      >>> portfolio
      [{'price': '32.20', 'name': 'AA', 'shares': '100'}, {'price': '91.10', 'name': 'IBM', 'shares': '50'}, {'price': '83.44', 'name': 'CAT', 'shares': '150'}, {'price': '51.23', 'name': 'MSFT', 'shares': '200'}, {'price': '40.37', 'name': 'GE', 'shares': '95'}, {'price': '65.10', 'name': 'MSFT', 'shares': '50'}, {'price': '70.44', 'name': 'IBM', 'shares': '100'}]
      
      >>> # Read only some of the data
      >>> shares_held = parse_csv('Data/portfolio.csv', select=['name','shares'])
      >>> shares_held
      [{'name': 'AA', 'shares': '100'}, {'name': 'IBM', 'shares': '50'}, {'name': 'CAT', 'shares': '150'}, {'name': 'MSFT', 'shares': '200'}, {'name': 'GE', 'shares': '95'}, {'name': 'MSFT', 'shares': '50'}, {'name': 'IBM', 'shares': '100'}]
      >>>
      

      練習(xí) 2.23 中給出了列選擇器的示例。

      然而,這里有一個(gè)方法可以做到這一點(diǎn):

      # fileparse.py
      import csv
      
      def parse_csv(filename, select=None):
          '''
          Parse a CSV file into a list of records
          '''
          with open(filename) as f:
              rows = csv.reader(f)
      
              # Read the file headers
              headers = next(rows)
      
              # If a column selector was given, find indices of the specified columns.
              # Also narrow the set of headers used for resulting dictionaries
              if select:
                  indices = [headers.index(colname) for colname in select]
                  headers = select
              else:
                  indices = []
      
              records = []
              for row in rows:
                  if not row:    # Skip rows with no data
                      continue
                  # Filter the row if specific columns were selected
                  if indices:
                      row = [ row[index] for index in indices ]
      
                  # Make a dictionary
                  record = dict(zip(headers, row))
                  records.append(record)
      
          return records
      

      這部分有一些棘手的問題,最重要的一個(gè)可能是列選擇到行索引的映射。例如,假設(shè)輸入文件具有以下標(biāo)題:

      >>> headers = ['name', 'date', 'time', 'shares', 'price']
      >>>
      

      現(xiàn)在,假設(shè)選定的列如下:

      >>> select = ['name', 'shares']
      >>>
      

      為了執(zhí)行正確的選擇,必須將選擇的列名映射到文件中的列索引。這就是該步驟正在執(zhí)行的操作:

      >>> indices = [headers.index(colname) for colname in select ]
      >>> indices
      [0, 3]
      >>>
      

      換句話說,名稱("name" )是第 0 列,股份數(shù)目("shares" )是第 3 列。

      當(dāng)從文件讀取數(shù)據(jù)行的時(shí)候,使用索引對(duì)其進(jìn)行過濾:

      >>> row = ['AA', '6/11/2007', '9:50am', '100', '32.20' ]
      >>> row = [ row[index] for index in indices ]
      >>> row
      ['AA', '100']
      >>>
      

      練習(xí) 3.5:執(zhí)行類型轉(zhuǎn)換

      修改 parse_csv() 函數(shù),以便可以選擇將類型轉(zhuǎn)換應(yīng)用到返回?cái)?shù)據(jù)上。例如:

      >>> portfolio = parse_csv('Data/portfolio.csv', types=[str, int, float])
      >>> portfolio
      [{'price': 32.2, 'name': 'AA', 'shares': 100}, {'price': 91.1, 'name': 'IBM', 'shares': 50}, {'price': 83.44, 'name': 'CAT', 'shares': 150}, {'price': 51.23, 'name': 'MSFT', 'shares': 200}, {'price': 40.37, 'name': 'GE', 'shares': 95}, {'price': 65.1, 'name': 'MSFT', 'shares': 50}, {'price': 70.44, 'name': 'IBM', 'shares': 100}]
      
      >>> shares_held = parse_csv('Data/portfolio.csv', select=['name', 'shares'], types=[str, int])
      >>> shares_held
      [{'name': 'AA', 'shares': 100}, {'name': 'IBM', 'shares': 50}, {'name': 'CAT', 'shares': 150}, {'name': 'MSFT', 'shares': 200}, {'name': 'GE', 'shares': 95}, {'name': 'MSFT', 'shares': 50}, {'name': 'IBM', 'shares': 100}]
      >>>
      

      練習(xí) 2.24 中已經(jīng)對(duì)此進(jìn)行了探索。需要將下列代碼片段插入到題解中:

      ...
      if types:
          row = [func(val) for func, val in zip(types, row) ]
      ...
      

      練習(xí) 3.6:處理無標(biāo)題的數(shù)據(jù)

      某些 CSV 文件不包含任何的標(biāo)題信息。例如,prices.csv 文件看起來像下面這樣:

      "AA",9.22
      "AXP",24.85
      "BA",44.85
      "BAC",11.27
      ...
      

      修改 parse_csv() 文件以便通過創(chuàng)建元組列表來處理此類文件。例如:

      >>> prices = parse_csv('Data/prices.csv', types=[str,float], has_headers=False)
      >>> prices
      [('AA', 9.22), ('AXP', 24.85), ('BA', 44.85), ('BAC', 11.27), ('C', 3.72), ('CAT', 35.46), ('CVX', 66.67), ('DD', 28.47), ('DIS', 24.22), ('GE', 13.48), ('GM', 0.75), ('HD', 23.16), ('HPQ', 34.35), ('IBM', 106.28), ('INTC', 15.72), ('JNJ', 55.16), ('JPM', 36.9), ('KFT', 26.11), ('KO', 49.16), ('MCD', 58.99), ('MMM', 57.1), ('MRK', 27.58), ('MSFT', 20.89), ('PFE', 15.19), ('PG', 51.94), ('T', 24.79), ('UTX', 52.61), ('VZ', 29.26), ('WMT', 49.74), ('XOM', 69.35)]
      >>>
      

      要執(zhí)行此更改,需要修改代碼以便數(shù)據(jù)的第一行不被解釋為標(biāo)題行。另外,需要確保不創(chuàng)建字典,因?yàn)椴辉儆锌捎糜诹忻逆I。

      練習(xí) 3.7:選擇其它的列分隔符

      盡管 CSV 文件非常普遍,但還可能會(huì)遇到使用其它列分隔符(如 制表符(tab) 或空格符(space))的文件。例如,如下所示的 Data/portfolio.dat 文件:

      name shares price
      "AA" 100 32.20
      "IBM" 50 91.10
      "CAT" 150 83.44
      "MSFT" 200 51.23
      "GE" 95 40.37
      "MSFT" 50 65.10
      "IBM" 100 70.44
      

      csv.reader() 函數(shù)允許像下面這樣指定不同的分隔符:

      rows = csv.reader(f, delimiter=' ')
      

      修改 parse_csv() 函數(shù)以便也允許修改分隔符。

      例如:

      >>> portfolio = parse_csv('Data/portfolio.dat', types=[str, int, float], delimiter=' ')
      >>> portfolio
      [{'price': '32.20', 'name': 'AA', 'shares': '100'}, {'price': '91.10', 'name': 'IBM', 'shares': '50'}, {'price': '83.44', 'name': 'CAT', 'shares': '150'}, {'price': '51.23', 'name': 'MSFT', 'shares': '200'}, {'price': '40.37', 'name': 'GE', 'shares': '95'}, {'price': '65.10', 'name': 'MSFT', 'shares': '50'}, {'price': '70.44', 'name': 'IBM', 'shares': '100'}]
      >>>
      

      說明

      到目前為止,如果你已經(jīng)完成,那么你創(chuàng)建了一個(gè)非常有用的庫函數(shù)。你可以使用它去解析任意的 CSV 文件,選擇感興趣的列,執(zhí)行類型轉(zhuǎn)換,而不用對(duì)文件或者 csv 模塊的內(nèi)部工作有太多的擔(dān)心。

      目錄 | 上一節(jié) (3.1 腳本) | 下一節(jié) (3.3 錯(cuò)誤檢查)

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

      posted @ 2021-03-01 23:16  codists  閱讀(349)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 久久久久久久久久久久中文字幕| 72种姿势欧美久久久久大黄蕉 | 亚洲国内精品一区二区| 加勒比无码人妻东京热 | 欧美人与zoxxxx另类| 国产精品一区二区性色av| 人妻日韩精品中文字幕| 中文字幕人妻日韩精品| 国产高清在线精品一本大道| 鲁鲁网亚洲站内射污| 亚洲小说乱欧美另类| 国产国语一级毛片| 免费国产va在线观看| 白水县| 国产激情精品一区二区三区| 亚洲国产欧美一区二区好看电影| 亚洲V天堂V手机在线| 成人自拍短视频午夜福利| 成人无码h真人在线网站| 疯狂做受xxxx高潮欧美日本| 男人的天堂av社区在线| 日本人一区二区在线观看| 福利一区二区不卡国产| 国产福利姬喷水福利在线观看| 国产精品亚洲五月天高清| 夜夜添无码试看一区二区三区| 亚洲av片在线免费观看| 国产成人无码aa精品一区| 亚洲人午夜精品射精日韩| 亚洲精品美女久久久久9999 | 欧美成人精品手机在线| 亚洲一品道一区二区三区| 亚洲一本大道无码av天堂| 国产激情精品一区二区三区| 亚洲AV成人片不卡无码| 久久久这里只有精品10| av午夜福利一片免费看久久| 久久99精品久久久久久| 国产农村老熟女国产老熟女| 亚洲中文字幕人妻系列| 国产熟睡乱子伦视频在线播放|