<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>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## 問題 你想寫一個裝飾器,既可以不傳參數給它,比如 `@decorator` ,也可以傳遞可選參數給它,比如 `@decorator(x,y,z)` 。 ## 解決方案 下面是9.5小節中日志裝飾器的一個修改版本: from functools import wraps, partial import logging def logged(func=None, *, level=logging.DEBUG, name=None, message=None): if func is None: return partial(logged, level=level, name=name, message=message) logname = name if name else func.__module__ log = logging.getLogger(logname) logmsg = message if message else func.__name__ @wraps(func) def wrapper(*args, **kwargs): log.log(level, logmsg) return func(*args, **kwargs) return wrapper # Example use @logged def add(x, y): return x + y @logged(level=logging.CRITICAL, name='example') def spam(): print('Spam!') 可以看到,`@logged` 裝飾器可以同時不帶參數或帶參數。 ## 討論 這里提到的這個問題就是通常所說的編程一致性問題。當我們使用裝飾器的時候,大部分程序員習慣了要么不給它們傳遞任何參數,要么給它們傳遞確切參數。其實從技術上來講,我們可以定義一個所有參數都是可選的裝飾器,就像下面這樣: @logged() def add(x, y): return x+y 但是,這種寫法并不符合我們的習慣,有時候程序員忘記加上后面的括號會導致錯誤。這里我們向你展示了如何以一致的編程風格來同時滿足沒有括號和有括號兩種情況。 為了理解代碼是如何工作的,你需要非常熟悉裝飾器是如何作用到函數上以及它們的調用規則。對于一個像下面這樣的簡單裝飾器: # Example use @logged def add(x, y): return x + y 這個調用序列跟下面等價: def add(x, y): return x + y add = logged(add) 這時候,被裝飾函數會被當做第一個參數直接傳遞給 `logged` 裝飾器。因此,`logged()` 中的第一個參數就是被包裝函數本身。所有其他參數都必須有默認值。 而對于一個下面這樣有參數的裝飾器: @logged(level=logging.CRITICAL, name='example') def spam(): print('Spam!') 調用序列跟下面等價: def spam(): print('Spam!') spam = logged(level=logging.CRITICAL, name='example')(spam) 初始調用 `logged()` 函數時,被包裝函數并沒有傳遞進來。因此在裝飾器內,它必須是可選的。這個反過來會迫使其他參數必須使用關鍵字來指定。并且,但這些參數被傳遞進來后,裝飾器要返回一個接受一個函數參數并包裝它的函數(參考9.5小節)。為了這樣做,我們使用了一個技巧,就是利用 `functools.partial` 。它會返回一個未完全初始化的自身,除了被包裝函數外其他參數都已經確定下來了。可以參考7.8小節獲取更多 `partial()` 方法的知識。
                  <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>

                              哎呀哎呀视频在线观看