<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ### 讀寫文件資源注意關閉 #### 使用 try...finally 關閉 在Python中,讀寫文件這樣的資源要特別注意,必須在使用完畢后正確關閉它們。正確關閉文件資源的一個方法是使用`try...finally`: ~~~ try: f = open('/path/to/file', 'r') f.read() finally: if f: f.close() ~~~ #### 使用 with 關閉 寫`try...finally`非常繁瑣。Python的`with`語句允許我們非常方便地使用資源,而不必擔心資源沒有關閉,所以上面的代碼可以簡化為: ~~~ with open('/path/to/file', 'r') as f: f.read() ~~~ 并不是只有`open()`函數返回的`fp`對象才能使用`with`語句。實際上,任何對象,只要正確實現了上下文管理,就可以用于`with`語句。 ### 實現上下文管理 實現上下文管理是通過`__enter__`和`__exit__`這兩個方法實現的。例如,下面的`class`實現了這兩個方法: ~~~ class Query(object): def __init__(self, name): self.name = name def __enter__(self): print('Begin') return self def __exit__(self, exc_type, exc_value, traceback): if exc_type: print('Error') else: print('End') def query(self): print('Query info about %s...' % self.name) ~~~ 這樣我們就可以把自己寫的資源對象用于`with`語句: ~~~ with Query('Bob') as q: q.query() @contextmanager ~~~ 編寫`__enter__`和`__exit__`仍然很繁瑣,因此Python的標準庫`contextlib`提供了更簡單的寫法,上面的代碼可以改寫如下: ~~~ from contextlib import contextmanager class Query(object): def __init__(self, name): self.name = name def query(self): print('Query info about %s...' % self.name) @contextmanager def create_query(name): print('Begin') q = Query(name) yield q print('End') ~~~ `@contextmanager`這個`decorator`接受一個`generator`,用`yield`語句把`with ... as var`把變量輸出出去,然后,`with`語句就可以正常地工作了: ~~~ with create_query('Bob') as q: q.query() ~~~ 很多時候,我們希望在某段代碼執行前后自動執行特定代碼,也可以用`@contextmanager`實現。例如: ~~~ @contextmanager def tag(name): print("<%s>" % name) yield print("</%s>" % name) with tag("h1"): print("hello") print("world") 上述代碼執行結果為: <h1> hello world </h1> ~~~ 代碼的執行順序是: `with`語句首先執行`yield`之前的語句,因此打印出`<h1>`; `yield`調用會執行`with`語句內部的所有語句,因此打印出`hello`和`world`; 最后執行`yield`之后的語句,打印出`</h1>`。 因此,`@contextmanager`讓我們通過編寫`generator`來簡化上下文管理。 ### @closing 如果一個對象沒有實現上下文,我們就不能把它用于`with`語句。這個時候,可以用`closing()`來把該對象變為上下文對象。例如,用`with`語句使用`urlopen()`: ~~~ from contextlib import closing from urllib.request import urlopen with closing(urlopen('https://www.python.org')) as page: for line in page: print(line) ~~~ `closing`也是一個經過`@contextmanager`裝飾的`generator`,這個`generator`編寫起來其實非常簡單: ~~~ @contextmanager def closing(thing): try: yield thing finally: thing.close() ~~~ 它的作用就是把任意對象變為上下文對象,并支持`with`語句。 `@contextlib`還有一些其他`decorator`,便于我們編寫更簡潔的代碼。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看