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

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

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

      翻譯:《實用的Python編程》06_01_Iteration_protocol

      目錄 | 上一節 (5.2 封裝) | 下一節 (6.2 自定義迭代)

      6.1 迭代協議

      本節將探究迭代的底層過程。

      迭代無處不在

      許多對象都支持迭代:

      a = 'hello'
      for c in a: # Loop over characters in a
          ...
      
      b = { 'name': 'Dave', 'password':'foo'}
      for k in b: # Loop over keys in dictionary
          ...
      
      c = [1,2,3,4]
      for i in c: # Loop over items in a list/tuple
          ...
      
      f = open('foo.txt')
      for x in f: # Loop over lines in a file
          ...
      

      迭代:協議

      考慮以下 for 語句:

      for x in obj:
          # statements
      

      for 語句的背后發生了什么?

      _iter = obj.__iter__()        # Get iterator object
      while True:
          try:
              x = _iter.__next__()  # Get next item
              # statements ...
          except StopIteration:     # No more items
              break
      

      所有可應用于 for-loop 的對象都實現了上述底層迭代協議。

      示例:手動迭代一個列表。

      >>> x = [1,2,3]
      >>> it = x.__iter__()
      >>> it
      <listiterator object at 0x590b0>
      >>> it.__next__()
      1
      >>> it.__next__()
      2
      >>> it.__next__()
      3
      >>> it.__next__()
      Traceback (most recent call last):
      File "<stdin>", line 1, in ? StopIteration
      >>>
      

      支持迭代

      如果想要將迭代添加到自己的對象中,那么了解迭代非常有用。例如:自定義容器。

      class Portfolio:
          def __init__(self):
              self.holdings = []
      
          def __iter__(self):
              return self.holdings.__iter__()
          ...
      
      port = Portfolio()
      for s in port:
          ...
      

      練習

      練習 6.1:迭代演示

      創建以下列表:

      a = [1,9,4,25,16]
      

      請手動迭代該列表:先調用 __iter__() 方法獲取一個迭代器,然后調用 __next__() 方法獲取下一個元素。

      >>> i = a.__iter__()
      >>> i
      <listiterator object at 0x64c10>
      >>> i.__next__()
      1
      >>> i.__next__()
      9
      >>> i.__next__()
      4
      >>> i.__next__()
      25
      >>> i.__next__()
      16
      >>> i.__next__()
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      StopIteration
      >>>
      

      內置函數 next() 是調用迭代器的 __next__() 方法的快捷方式。嘗試在一個文件對象上使用 next() 方法:

      >>> f = open('Data/portfolio.csv')
      >>> f.__iter__()    # Note: This returns the file itself
      <_io.TextIOWrapper name='Data/portfolio.csv' mode='r' encoding='UTF-8'>
      >>> next(f)
      'name,shares,price\n'
      >>> next(f)
      '"AA",100,32.20\n'
      >>> next(f)
      '"IBM",50,91.10\n'
      >>>
      

      持續調用 next(f),直到文件末尾。觀察會發生什么。

      練習 6.2:支持迭代

      有時候,你可能想要使自己的類對象支持迭代——尤其是你的類對象封裝了已有的列表或者其它可迭代對象時。請在新的 portfolio.py 文件中定義如下類:

      # portfolio.py
      
      class Portfolio:
      
          def __init__(self, holdings):
              self._holdings = holdings
      
          @property
          def total_cost(self):
              return sum([s.cost for s in self._holdings])
      
          def tabulate_shares(self):
              from collections import Counter
              total_shares = Counter()
              for s in self._holdings:
                  total_shares[s.name] += s.shares
              return total_shares
      

      Portfolio 類封裝了一個列表,同時擁有一些方法,如: total_cost property。請修改 report.py 文件中的 read_portfolio() 函數,以便 read_portfolio() 函數能夠像下面這樣創建 Portfolio 類的實例:

      # report.py
      ...
      
      import fileparse
      from stock import Stock
      from portfolio import Portfolio
      
      def read_portfolio(filename):
          '''
          Read a stock portfolio file into a list of dictionaries with keys
          name, shares, and price.
          '''
          with open(filename) as file:
              portdicts = fileparse.parse_csv(file,
                                              select=['name','shares','price'],
                                              types=[str,int,float])
      
          portfolio = [ Stock(d['name'], d['shares'], d['price']) for d in portdicts ]
          return Portfolio(portfolio)
      ...
      

      接著運行 report.py 程序。你會發現程序運行失敗,原因很明顯,因為 Portfolio 的實例不是可迭代對象。

      >>> import report
      >>> report.portfolio_report('Data/portfolio.csv', 'Data/prices.csv')
      ... crashes ...
      

      可以通過修改 Portfolio 類,使 Portfolio 類支持迭代來解決此問題:

      class Portfolio:
      
          def __init__(self, holdings):
              self._holdings = holdings
      
          def __iter__(self):
              return self._holdings.__iter__()
      
          @property
          def total_cost(self):
              return sum([s.shares*s.price for s in self._holdings])
      
          def tabulate_shares(self):
              from collections import Counter
              total_shares = Counter()
              for s in self._holdings:
                  total_shares[s.name] += s.shares
              return total_shares
      

      修改完成后, report.py 程序應該能夠再次正常運行。同時,請修改 pcost.py 程序,以便能夠像下面這樣使用新的 Portfolio 對象:

      # pcost.py
      
      import report
      
      def portfolio_cost(filename):
          '''
          Computes the total cost (shares*price) of a portfolio file
          '''
          portfolio = report.read_portfolio(filename)
          return portfolio.total_cost
      ...
      

      pcost.py 程序進行測試并確保其能正常工作:

      >>> import pcost
      >>> pcost.portfolio_cost('Data/portfolio.csv')
      44671.15
      >>>
      

      練習 6.3:創建一個更合適的容器

      通常,我們創建一個容器類時,不僅希望該類能夠迭代,同時也希望該類能夠具有一些其它用途。請修改 Portfolio 類,使其具有以下這些特殊方法:

      class Portfolio:
          def __init__(self, holdings):
              self._holdings = holdings
      
          def __iter__(self):
              return self._holdings.__iter__()
      
          def __len__(self):
              return len(self._holdings)
      
          def __getitem__(self, index):
              return self._holdings[index]
      
          def __contains__(self, name):
              return any([s.name == name for s in self._holdings])
      
          @property
          def total_cost(self):
              return sum([s.shares*s.price for s in self._holdings])
      
          def tabulate_shares(self):
              from collections import Counter
              total_shares = Counter()
              for s in self._holdings:
                  total_shares[s.name] += s.shares
              return total_shares
      

      現在,使用 Portfolio 類進行一些實驗:

      >>> import report
      >>> portfolio = report.read_portfolio('Data/portfolio.csv')
      >>> len(portfolio)
      7
      >>> portfolio[0]
      Stock('AA', 100, 32.2)
      >>> portfolio[1]
      Stock('IBM', 50, 91.1)
      >>> portfolio[0:3]
      [Stock('AA', 100, 32.2), Stock('IBM', 50, 91.1), Stock('CAT', 150, 83.44)]
      >>> 'IBM' in portfolio
      True
      >>> 'AAPL' in portfolio
      False
      >>>
      

      有關上述代碼的一個重要發現——通常,如果一段代碼和 Python 的其它代碼"類似(speaks the common vocabulary of how other parts of Python normally work)",那么該代碼被認為是 “Pythonic” 的。同理,對于容器對象,其重要組成部分應該包括:支持迭代、可以進行索引、對所包含的元素進行判斷,以及其它操作等等。

      目錄 | 上一節 (5.2 封裝) | 下一節 (6.2 自定義迭代)

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

      posted @ 2021-03-15 14:42  codists  閱讀(262)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 人人妻人人澡人人爽| 青青青爽在线视频观看| 国产午夜福利片在线观看| 亚洲av伊人久久综合性色| 人妻少妇偷人一区二区| 精品一区二区三区无码视频| 国产情侣一区二区三区| 免费看成人毛片无码视频| 国产成人av电影在线观看第一页| 天堂在线精品亚洲综合网| 久久夜色精品国产亚av| 国产精品久久蜜臀av| 夜夜添无码试看一区二区三区| 六十路老熟妇乱子伦视频| 人妻一区二区三区三区| 一区二区三区国产综合在线| 亚洲男人第一无码av网站| 亚洲欧美自偷自拍视频图片| 女同性恋一区二区三区视频| 性做久久久久久久久| 人妻丰满熟妇av无码区| 托克逊县| 色窝窝免费播放视频在线| 国产欧美va欧美va在线| 国产叼嘿视频一区二区三区 | 国产网红主播精品一区| 国产深夜福利在线免费观看 | 成人又黄又爽又色的视频| 亚洲日韩AV秘 无码一区二区| 综合亚洲网| 91亚洲精品一区二区三区| 成人看的污污超级黄网站免费| 久青草精品视频在线观看| 黄又色又污又爽又高潮| 久久天天躁狠狠躁夜夜婷| 一区二区三区成人| 福利网午夜视频一区二区| 日本亚洲一区二区精品久久| 浓毛老太交欧美老妇热爱乱| 日韩中av免费在线观看| 亚洲欧美偷国产日韩|