import requests
r = requests.get('http://www.jerrylsu.net/articles/2020/programming-Python-Decorator.html')
r.encoding
'ISO-8859-1'
r.encoding = 'utf-8'
r.text
'<!DOCTYPE html>\n<html lang="en" prefix="og: http://ogp.me/ns# fb: https://www.facebook.com/2008/fbml">\n<head>\n    <title>Python Decorator - Jerrylsu.net</title>\n    <!-- Using the latest rendering mode for IE -->\n    <meta http-equiv="X-UA-Compatible" content="IE=edge">\n    <meta charset="utf-8">\n    <meta name="viewport" content="width=device-width, initial-scale=1.0">\n\n\n    <link href="/jerry.jpg" rel="icon">\n\n<link rel="canonical" href="/articles/2020/programming-Python-Decorator.html">\n\n        <meta name="author" content="Jerry Su" />\n        <meta name="keywords" content="Python" />\n        <meta name="description" content="0. 装饰器¶装饰器:接收一个函数(被装饰的函数)对象,返回一个函数(已装饰的函数)对象。动态的给一个对象添加额外职责,即装饰器设计模式。 装饰器的典型行为:把被装饰的函数替换为新函数,二者接收的参数相同,并返回被装饰函数本该的返回值,同时增加一些额外操作。 func = factorial, factorial = clocked clock是装饰器 factorial是被装饰函数 clocked是被装饰后的函数 factorial作为func参数传递给装饰器clock,装饰器clock返回clocked函数并复制给factorial。func是clocked的自由变量,两者构成闭包。 当调用函数factorial时,实际上调用函数locked,而locked函数中func则为被装饰的函数factorial。" />\n\n        <meta property="og:site_name" content="Jerrylsu.net" />\n        <meta property="og:type" content="article"/>\n        <meta property="og:title" content="Python Decorator"/>\n        <meta property="og:url" content="/articles/2020/programming-Python-Decorator.html"/>\n        <meta property="og:description" content="0. 装饰器¶装饰器:接收一个函数(被装饰的函数)对象,返回一个函数(已装饰的函数)对象。动态的给一个对象添加额外职责,即装饰器设计模式。 装饰器的典型行为:把被装饰的函数替换为新函数,二者接收的参数相同,并返回被装饰函数本该的返回值,同时增加一些额外操作。 func = factorial, factorial = clocked clock是装饰器 factorial是被装饰函数 clocked是被装饰后的函数 factorial作为func参数传递给装饰器clock,装饰器clock返回clocked函数并复制给factorial。func是clocked的自由变量,两者构成闭包。 当调用函数factorial时,实际上调用函数locked,而locked函数中func则为被装饰的函数factorial。"/>\n        <meta property="article:published_time" content="2020-12-20" />\n            <meta property="article:section" content="Programming" />\n            <meta property="article:tag" content="Python" />\n            <meta property="article:author" content="Jerry Su" />\n\n\n\n    <!-- Bootstrap -->\n        <link rel="stylesheet" href="/theme/css/bootstrap.min.css" type="text/css"/>\n    <link href="/theme/css/font-awesome.min.css" rel="stylesheet">\n\n    <link href="/theme/css/pygments/colorful.css" rel="stylesheet">\n    <link href="/theme/tipuesearch/tipuesearch.css" rel="stylesheet">\n    <link rel="stylesheet" href="/theme/css/style.css" type="text/css"/>\n\n\n\n</head>\n<body>\n\n<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">\n    <div class="container-fluid">\n        <div class="navbar-header">\n            <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-ex1-collapse">\n                <span class="sr-only">Toggle navigation</span>\n                <span class="icon-bar"></span>\n                <span class="icon-bar"></span>\n                <span class="icon-bar"></span>\n            </button>\n            <a href="/" class="navbar-brand">\nJerrylsu.net            </a>\n        </div>\n        <div class="collapse navbar-collapse navbar-ex1-collapse">\n            <ul class="nav navbar-nav">\n                         <li><a href="/pages/about.html">\n                             ABOUT\n                          </a></li>\n                         <li><a href="/pages/algorithms.html">\n                             ALGORITHMS\n                          </a></li>\n                         <li><a href="/pages/books.html">\n                             BOOKS\n                          </a></li>\n                         <li><a href="/pages/projects.html">\n                             PROJECTS\n                          </a></li>\n                         <li><a href="/pages/python.html">\n                             PYTHON\n                          </a></li>\n                         <li><a href="/pages/tensorflow.html">\n                             TENSORFLOW\n                          </a></li>\n            </ul>\n            <ul class="nav navbar-nav navbar-right">\n              <li><span>\n                <form class="navbar-search" action="/search.html">\n                  <input type="text" class="search-query" placeholder="Search" name="q" id="tipue_search_input" required>\n                </form></span>\n              </li>\n              <li><a href="/articles/index.html"><i class="fa fa-th-list"></i><span class="icon-label">Archives</span></a></li>\n            </ul>\n        </div>\n        <!-- /.navbar-collapse -->\n    </div>\n</div> <!-- /.navbar -->\n\n<!-- Banner -->\n<!-- End Banner -->\n\n<!-- Content Container -->\n<div class="container-fluid">\n    <div class="row">\n        <div class="col-sm-9 col-sm-push-3">\n            <ol class="breadcrumb">\n                <li><a href="" title="Jerrylsu.net"><i class="fa fa-home fa-lg"></i></a></li>\n                <li><a href="/categories/programming.html" title="Programming">Programming</a></li>\n                <li class="active">Python Decorator</li>\n            </ol>\n    <section id="content">\n        <article>\n            <header class="page-header">\n                <h1>\n                    <a href="/articles/2020/programming-Python-Decorator.html"\n                       rel="bookmark"\n                       title="Permalink to Python Decorator">\n                        Python Decorator\n                    </a>\n                </h1>\n            </header>\n            <div class="entry-content">\n                <div class="panel">\n                    <div class="panel-body">\n<footer class="post-info">\n    <span class="label label-default">Date</span>\n    <span class="published">\n        <i class="fa fa-calendar"></i><time datetime="2020-12-20T10:17:17+08:00"> 2020-12-20 Sun</time>\n    </span>\n\n\n\n\n\n<span class="label label-default">Tags</span>\n\t<a href="/tags/python.html">Python</a>\n    \n</footer><!-- /.post-info -->                    </div>\n                </div>\n                <style type="text/css">/*!\n*\n* IPython notebook\n*\n*/\n/* CSS font colors for translated ANSI escape sequences */\n/* The color values are a mix of\n   http://www.xcolors.net/dl/baskerville-ivorylight and\n   http://www.xcolors.net/dl/euphrasia */\n.ansi-black-fg {\n  color: #3E424D;\n}\n.ansi-black-bg {\n  background-color: #3E424D;\n}\n.ansi-black-intense-fg {\n  color: #282C36;\n}\n.ansi-black-intense-bg {\n  background-color: #282C36;\n}\n.ansi-red-fg {\n  color: #E75C58;\n}\n.ansi-red-bg {\n  background-color: #E75C58;\n}\n.ansi-red-intense-fg {\n  color: #B22B31;\n}\n.ansi-red-intense-bg {\n  background-color: #B22B31;\n}\n.ansi-green-fg {\n  color: #00A250;\n}\n.ansi-green-bg {\n  background-color: #00A250;\n}\n.ansi-green-intense-fg {\n  color: #007427;\n}\n.ansi-green-intense-bg {\n  background-color: #007427;\n}\n.ansi-yellow-fg {\n  color: #DDB62B;\n}\n.ansi-yellow-bg {\n  background-color: #DDB62B;\n}\n.ansi-yellow-intense-fg {\n  color: #B27D12;\n}\n.ansi-yellow-intense-bg {\n  background-color: #B27D12;\n}\n.ansi-blue-fg {\n  color: #208FFB;\n}\n.ansi-blue-bg {\n  background-color: #208FFB;\n}\n.ansi-blue-intense-fg {\n  color: #0065CA;\n}\n.ansi-blue-intense-bg {\n  background-color: #0065CA;\n}\n.ansi-magenta-fg {\n  color: #D160C4;\n}\n.ansi-magenta-bg {\n  background-color: #D160C4;\n}\n.ansi-magenta-intense-fg {\n  color: #A03196;\n}\n.ansi-magenta-intense-bg {\n  background-color: #A03196;\n}\n.ansi-cyan-fg {\n  color: #60C6C8;\n}\n.ansi-cyan-bg {\n  background-color: #60C6C8;\n}\n.ansi-cyan-intense-fg {\n  color: #258F8F;\n}\n.ansi-cyan-intense-bg {\n  background-color: #258F8F;\n}\n.ansi-white-fg {\n  color: #C5C1B4;\n}\n.ansi-white-bg {\n  background-color: #C5C1B4;\n}\n.ansi-white-intense-fg {\n  color: #A1A6B2;\n}\n.ansi-white-intense-bg {\n  background-color: #A1A6B2;\n}\n.ansi-default-inverse-fg {\n  color: #FFFFFF;\n}\n.ansi-default-inverse-bg {\n  background-color: #000000;\n}\n.ansi-bold {\n  font-weight: bold;\n}\n.ansi-underline {\n  text-decoration: underline;\n}\n/* The following styles are deprecated an will be removed in a future version */\n.ansibold {\n  font-weight: bold;\n}\n.ansi-inverse {\n  outline: 0.5px dotted;\n}\n/* use dark versions for foreground, to improve visibility */\n.ansiblack {\n  color: black;\n}\n.ansired {\n  color: darkred;\n}\n.ansigreen {\n  color: darkgreen;\n}\n.ansiyellow {\n  color: #c4a000;\n}\n.ansiblue {\n  color: darkblue;\n}\n.ansipurple {\n  color: darkviolet;\n}\n.ansicyan {\n  color: steelblue;\n}\n.ansigray {\n  color: gray;\n}\n/* and light for background, for the same reason */\n.ansibgblack {\n  background-color: black;\n}\n.ansibgred {\n  background-color: red;\n}\n.ansibggreen {\n  background-color: green;\n}\n.ansibgyellow {\n  background-color: yellow;\n}\n.ansibgblue {\n  background-color: blue;\n}\n.ansibgpurple {\n  background-color: magenta;\n}\n.ansibgcyan {\n  background-color: cyan;\n}\n.ansibggray {\n  background-color: gray;\n}\ndiv.cell {\n  /* Old browsers */\n  display: -webkit-box;\n  -webkit-box-orient: vertical;\n  -webkit-box-align: stretch;\n  display: -moz-box;\n  -moz-box-orient: vertical;\n  -moz-box-align: stretch;\n  display: box;\n  box-orient: vertical;\n  box-align: stretch;\n  /* Modern browsers */\n  display: flex;\n  flex-direction: column;\n  align-items: stretch;\n  border-radius: 2px;\n  box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n  border-width: 1px;\n  border-style: solid;\n  border-color: transparent;\n  width: 100%;\n  padding: 5px;\n  /* This acts as a spacer between cells, that is outside the border */\n  margin: 0px;\n  outline: none;\n  position: relative;\n  overflow: visible;\n}\ndiv.cell:before {\n  position: absolute;\n  display: block;\n  top: -1px;\n  left: -1px;\n  width: 5px;\n  height: calc(100% +  2px);\n  content: \'\';\n  background: transparent;\n}\ndiv.cell.jupyter-soft-selected {\n  border-left-color: #E3F2FD;\n  border-left-width: 1px;\n  padding-left: 5px;\n  border-right-color: #E3F2FD;\n  border-right-width: 1px;\n  background: #E3F2FD;\n}\n@media print {\n  div.cell.jupyter-soft-selected {\n    border-color: transparent;\n  }\n}\ndiv.cell.selected,\ndiv.cell.selected.jupyter-soft-selected {\n  border-color: #ababab;\n}\ndiv.cell.selected:before,\ndiv.cell.selected.jupyter-soft-selected:before {\n  position: absolute;\n  display: block;\n  top: -1px;\n  left: -1px;\n  width: 5px;\n  height: calc(100% +  2px);\n  content: \'\';\n  background: #42A5F5;\n}\n@media print {\n  div.cell.selected,\n  div.cell.selected.jupyter-soft-selected {\n    border-color: transparent;\n  }\n}\n.edit_mode div.cell.selected {\n  border-color: #66BB6A;\n}\n.edit_mode div.cell.selected:before {\n  position: absolute;\n  display: block;\n  top: -1px;\n  left: -1px;\n  width: 5px;\n  height: calc(100% +  2px);\n  content: \'\';\n  background: #66BB6A;\n}\n@media print {\n  .edit_mode div.cell.selected {\n    border-color: transparent;\n  }\n}\n.prompt {\n  /* This needs to be wide enough for 3 digit prompt numbers: In[100]: */\n  min-width: 14ex;\n  /* This padding is tuned to match the padding on the CodeMirror editor. */\n  padding: 0.4em;\n  margin: 0px;\n  font-family: monospace;\n  text-align: right;\n  /* This has to match that of the the CodeMirror class line-height below */\n  line-height: 1.21429em;\n  /* Don\'t highlight prompt number selection */\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  /* Use default cursor */\n  cursor: default;\n}\n@media (max-width: 540px) {\n  .prompt {\n    text-align: left;\n  }\n}\ndiv.inner_cell {\n  min-width: 0;\n  /* Old browsers */\n  display: -webkit-box;\n  -webkit-box-orient: vertical;\n  -webkit-box-align: stretch;\n  display: -moz-box;\n  -moz-box-orient: vertical;\n  -moz-box-align: stretch;\n  display: box;\n  box-orient: vertical;\n  box-align: stretch;\n  /* Modern browsers */\n  display: flex;\n  flex-direction: column;\n  align-items: stretch;\n  /* Old browsers */\n  -webkit-box-flex: 1;\n  -moz-box-flex: 1;\n  box-flex: 1;\n  /* Modern browsers */\n  flex: 1;\n}\n/* input_area and input_prompt must match in top border and margin for alignment */\ndiv.input_area {\n  border: 1px solid #cfcfcf;\n  border-radius: 2px;\n  background: #f7f7f7;\n  line-height: 1.21429em;\n}\n/* This is needed so that empty prompt areas can collapse to zero height when there\n   is no content in the output_subarea and the prompt. The main purpose of this is\n   to make sure that empty JavaScript output_subareas have no height. */\ndiv.prompt:empty {\n  padding-top: 0;\n  padding-bottom: 0;\n}\ndiv.unrecognized_cell {\n  padding: 5px 5px 5px 0px;\n  /* Old browsers */\n  display: -webkit-box;\n  -webkit-box-orient: horizontal;\n  -webkit-box-align: stretch;\n  display: -moz-box;\n  -moz-box-orient: horizontal;\n  -moz-box-align: stretch;\n  display: box;\n  box-orient: horizontal;\n  box-align: stretch;\n  /* Modern browsers */\n  display: flex;\n  flex-direction: row;\n  align-items: stretch;\n}\ndiv.unrecognized_cell .inner_cell {\n  border-radius: 2px;\n  padding: 5px;\n  font-weight: bold;\n  color: red;\n  border: 1px solid #cfcfcf;\n  background: #eaeaea;\n}\ndiv.unrecognized_cell .inner_cell a {\n  color: inherit;\n  text-decoration: none;\n}\ndiv.unrecognized_cell .inner_cell a:hover {\n  color: inherit;\n  text-decoration: none;\n}\n@media (max-width: 540px) {\n  div.unrecognized_cell > div.prompt {\n    display: none;\n  }\n}\ndiv.code_cell {\n  /* avoid page breaking on code cells when printing */\n}\n@media print {\n  div.code_cell {\n    page-break-inside: avoid;\n  }\n}\n/* any special styling for code cells that are currently running goes here */\ndiv.input {\n  page-break-inside: avoid;\n  /* Old browsers */\n  display: -webkit-box;\n  -webkit-box-orient: horizontal;\n  -webkit-box-align: stretch;\n  display: -moz-box;\n  -moz-box-orient: horizontal;\n  -moz-box-align: stretch;\n  display: box;\n  box-orient: horizontal;\n  box-align: stretch;\n  /* Modern browsers */\n  display: flex;\n  flex-direction: row;\n  align-items: stretch;\n}\n@media (max-width: 540px) {\n  div.input {\n    /* Old browsers */\n    display: -webkit-box;\n    -webkit-box-orient: vertical;\n    -webkit-box-align: stretch;\n    display: -moz-box;\n    -moz-box-orient: vertical;\n    -moz-box-align: stretch;\n    display: box;\n    box-orient: vertical;\n    box-align: stretch;\n    /* Modern browsers */\n    display: flex;\n    flex-direction: column;\n    align-items: stretch;\n  }\n}\n/* input_area and input_prompt must match in top border and margin for alignment */\ndiv.input_prompt {\n  color: #303F9F;\n  border-top: 1px solid transparent;\n}\ndiv.input_area > div.highlight {\n  margin: 0.4em;\n  border: none;\n  padding: 0px;\n  background-color: transparent;\n}\ndiv.input_area > div.highlight > pre {\n  margin: 0px;\n  border: none;\n  padding: 0px;\n  background-color: transparent;\n}\n/* The following gets added to the <head> if it is detected that the user has a\n * monospace font with inconsistent normal/bold/italic height.  See\n * notebookmain.js.  Such fonts will have keywords vertically offset with\n * respect to the rest of the text.  The user should select a better font.\n * See: https://github.com/ipython/ipython/issues/1503\n *\n * .CodeMirror span {\n *      vertical-align: bottom;\n * }\n */\n.CodeMirror {\n  line-height: 1.21429em;\n  /* Changed from 1em to our global default */\n  font-size: 14px;\n  height: auto;\n  /* Changed to auto to autogrow */\n  background: none;\n  /* Changed from white to allow our bg to show through */\n}\n.CodeMirror-scroll {\n  /*  The CodeMirror docs are a bit fuzzy on if overflow-y should be hidden or visible.*/\n  /*  We have found that if it is visible, vertical scrollbars appear with font size changes.*/\n  overflow-y: hidden;\n  overflow-x: auto;\n}\n.CodeMirror-lines {\n  /* In CM2, this used to be 0.4em, but in CM3 it went to 4px. We need the em value because */\n  /* we have set a different line-height and want this to scale with that. */\n  /* Note that this should set vertical padding only, since CodeMirror assumes\n       that horizontal padding will be set on CodeMirror pre */\n  padding: 0.4em 0;\n}\n.CodeMirror-linenumber {\n  padding: 0 8px 0 4px;\n}\n.CodeMirror-gutters {\n  border-bottom-left-radius: 2px;\n  border-top-left-radius: 2px;\n}\n.CodeMirror pre {\n  /* In CM3 this went to 4px from 0 in CM2. This sets horizontal padding only,\n    use .CodeMirror-lines for vertical */\n  padding: 0 0.4em;\n  border: 0;\n  border-radius: 0;\n}\n.CodeMirror-cursor {\n  border-left: 1.4px solid black;\n}\n@media screen and (min-width: 2138px) and (max-width: 4319px) {\n  .CodeMirror-cursor {\n    border-left: 2px solid black;\n  }\n}\n@media screen and (min-width: 4320px) {\n  .CodeMirror-cursor {\n    border-left: 4px solid black;\n  }\n}\n/*\n\nOriginal style from softwaremaniacs.org (c) Ivan Sagalaev <Maniac@SoftwareManiacs.Org>\nAdapted from GitHub theme\n\n*/\n.highlight-base {\n  color: #000;\n}\n.highlight-variable {\n  color: #000;\n}\n.highlight-variable-2 {\n  color: #1a1a1a;\n}\n.highlight-variable-3 {\n  color: #333333;\n}\n.highlight-string {\n  color: #BA2121;\n}\n.highlight-comment {\n  color: #408080;\n  font-style: italic;\n}\n.highlight-number {\n  color: #080;\n}\n.highlight-atom {\n  color: #88F;\n}\n.highlight-keyword {\n  color: #008000;\n  font-weight: bold;\n}\n.highlight-builtin {\n  color: #008000;\n}\n.highlight-error {\n  color: #f00;\n}\n.highlight-operator {\n  color: #AA22FF;\n  font-weight: bold;\n}\n.highlight-meta {\n  color: #AA22FF;\n}\n/* previously not defined, copying from default codemirror */\n.highlight-def {\n  color: #00f;\n}\n.highlight-string-2 {\n  color: #f50;\n}\n.highlight-qualifier {\n  color: #555;\n}\n.highlight-bracket {\n  color: #997;\n}\n.highlight-tag {\n  color: #170;\n}\n.highlight-attribute {\n  color: #00c;\n}\n.highlight-header {\n  color: blue;\n}\n.highlight-quote {\n  color: #090;\n}\n.highlight-link {\n  color: #00c;\n}\n/* apply the same style to codemirror */\n.cm-s-ipython span.cm-keyword {\n  color: #008000;\n  font-weight: bold;\n}\n.cm-s-ipython span.cm-atom {\n  color: #88F;\n}\n.cm-s-ipython span.cm-number {\n  color: #080;\n}\n.cm-s-ipython span.cm-def {\n  color: #00f;\n}\n.cm-s-ipython span.cm-variable {\n  color: #000;\n}\n.cm-s-ipython span.cm-operator {\n  color: #AA22FF;\n  font-weight: bold;\n}\n.cm-s-ipython span.cm-variable-2 {\n  color: #1a1a1a;\n}\n.cm-s-ipython span.cm-variable-3 {\n  color: #333333;\n}\n.cm-s-ipython span.cm-comment {\n  color: #408080;\n  font-style: italic;\n}\n.cm-s-ipython span.cm-string {\n  color: #BA2121;\n}\n.cm-s-ipython span.cm-string-2 {\n  color: #f50;\n}\n.cm-s-ipython span.cm-meta {\n  color: #AA22FF;\n}\n.cm-s-ipython span.cm-qualifier {\n  color: #555;\n}\n.cm-s-ipython span.cm-builtin {\n  color: #008000;\n}\n.cm-s-ipython span.cm-bracket {\n  color: #997;\n}\n.cm-s-ipython span.cm-tag {\n  color: #170;\n}\n.cm-s-ipython span.cm-attribute {\n  color: #00c;\n}\n.cm-s-ipython span.cm-header {\n  color: blue;\n}\n.cm-s-ipython span.cm-quote {\n  color: #090;\n}\n.cm-s-ipython span.cm-link {\n  color: #00c;\n}\n.cm-s-ipython span.cm-error {\n  color: #f00;\n}\n.cm-s-ipython span.cm-tab {\n  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAMCAYAAAAkuj5RAAAAAXNSR0IArs4c6QAAAGFJREFUSMft1LsRQFAQheHPowAKoACx3IgEKtaEHujDjORSgWTH/ZOdnZOcM/sgk/kFFWY0qV8foQwS4MKBCS3qR6ixBJvElOobYAtivseIE120FaowJPN75GMu8j/LfMwNjh4HUpwg4LUAAAAASUVORK5CYII=);\n  background-position: right;\n  background-repeat: no-repeat;\n}\ndiv.output_wrapper {\n  /* this position must be relative to enable descendents to be absolute within it */\n  position: relative;\n  /* Old browsers */\n  display: -webkit-box;\n  -webkit-box-orient: vertical;\n  -webkit-box-align: stretch;\n  display: -moz-box;\n  -moz-box-orient: vertical;\n  -moz-box-align: stretch;\n  display: box;\n  box-orient: vertical;\n  box-align: stretch;\n  /* Modern browsers */\n  display: flex;\n  flex-direction: column;\n  align-items: stretch;\n  z-index: 1;\n}\n/* class for the output area when it should be height-limited */\ndiv.output_scroll {\n  /* ideally, this would be max-height, but FF barfs all over that */\n  height: 24em;\n  /* FF needs this *and the wrapper* to specify full width, or it will shrinkwrap */\n  width: 100%;\n  overflow: auto;\n  border-radius: 2px;\n  -webkit-box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);\n  box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.8);\n  display: block;\n}\n/* output div while it is collapsed */\ndiv.output_collapsed {\n  margin: 0px;\n  padding: 0px;\n  /* Old browsers */\n  display: -webkit-box;\n  -webkit-box-orient: vertical;\n  -webkit-box-align: stretch;\n  display: -moz-box;\n  -moz-box-orient: vertical;\n  -moz-box-align: stretch;\n  display: box;\n  box-orient: vertical;\n  box-align: stretch;\n  /* Modern browsers */\n  display: flex;\n  flex-direction: column;\n  align-items: stretch;\n}\ndiv.out_prompt_overlay {\n  height: 100%;\n  padding: 0px 0.4em;\n  position: absolute;\n  border-radius: 2px;\n}\ndiv.out_prompt_overlay:hover {\n  /* use inner shadow to get border that is computed the same on WebKit/FF */\n  -webkit-box-shadow: inset 0 0 1px #000;\n  box-shadow: inset 0 0 1px #000;\n  background: rgba(240, 240, 240, 0.5);\n}\ndiv.output_prompt {\n  color: #D84315;\n}\n/* This class is the outer container of all output sections. */\ndiv.output_area {\n  padding: 0px;\n  page-break-inside: avoid;\n  /* Old browsers */\n  display: -webkit-box;\n  -webkit-box-orient: horizontal;\n  -webkit-box-align: stretch;\n  display: -moz-box;\n  -moz-box-orient: horizontal;\n  -moz-box-align: stretch;\n  display: box;\n  box-orient: horizontal;\n  box-align: stretch;\n  /* Modern browsers */\n  display: flex;\n  flex-direction: row;\n  align-items: stretch;\n}\ndiv.output_area .MathJax_Display {\n  text-align: left !important;\n}\ndiv.output_area \ndiv.output_area \ndiv.output_area img,\ndiv.output_area svg {\n  max-width: 100%;\n  height: auto;\n}\ndiv.output_area img.unconfined,\ndiv.output_area svg.unconfined {\n  max-width: none;\n}\ndiv.output_area .mglyph > img {\n  max-width: none;\n}\n/* This is needed to protect the pre formating from global settings such\n   as that of bootstrap */\n.output {\n  /* Old browsers */\n  display: -webkit-box;\n  -webkit-box-orient: vertical;\n  -webkit-box-align: stretch;\n  display: -moz-box;\n  -moz-box-orient: vertical;\n  -moz-box-align: stretch;\n  display: box;\n  box-orient: vertical;\n  box-align: stretch;\n  /* Modern browsers */\n  display: flex;\n  flex-direction: column;\n  align-items: stretch;\n}\n@media (max-width: 540px) {\n  div.output_area {\n    /* Old browsers */\n    display: -webkit-box;\n    -webkit-box-orient: vertical;\n    -webkit-box-align: stretch;\n    display: -moz-box;\n    -moz-box-orient: vertical;\n    -moz-box-align: stretch;\n    display: box;\n    box-orient: vertical;\n    box-align: stretch;\n    /* Modern browsers */\n    display: flex;\n    flex-direction: column;\n    align-items: stretch;\n  }\n}\ndiv.output_area pre {\n  margin: 0;\n  padding: 1px 0 1px 0;\n  border: 0;\n  vertical-align: baseline;\n  color: black;\n  background-color: transparent;\n  border-radius: 0;\n}\n/* This class is for the output subarea inside the output_area and after\n   the prompt div. */\ndiv.output_subarea {\n  overflow-x: auto;\n  padding: 0.4em;\n  /* Old browsers */\n  -webkit-box-flex: 1;\n  -moz-box-flex: 1;\n  box-flex: 1;\n  /* Modern browsers */\n  flex: 1;\n  max-width: calc(100% - 14ex);\n}\ndiv.output_scroll div.output_subarea {\n  overflow-x: visible;\n}\n/* The rest of the output_* classes are for special styling of the different\n   output types */\n/* all text output has this class: */\ndiv.output_text {\n  text-align: left;\n  color: #000;\n  /* This has to match that of the the CodeMirror class line-height below */\n  line-height: 1.21429em;\n}\n/* stdout/stderr are \'text\' as well as \'stream\', but execute_result/error are *not* streams */\ndiv.output_stderr {\n  background: #fdd;\n  /* very light red background for stderr */\n}\ndiv.output_latex {\n  text-align: left;\n}\n/* Empty output_javascript divs should have no height */\ndiv.output_javascript:empty {\n  padding: 0;\n}\n.js-error {\n  color: darkred;\n}\n/* raw_input styles */\ndiv.raw_input_container {\n  line-height: 1.21429em;\n  padding-top: 5px;\n}\npre.raw_input_prompt {\n  /* nothing needed here. */\n}\ninput.raw_input {\n  font-family: monospace;\n  font-size: inherit;\n  color: inherit;\n  width: auto;\n  /* make sure input baseline aligns with prompt */\n  vertical-align: baseline;\n  /* padding + margin = 0.5em between prompt and cursor */\n  padding: 0em 0.25em;\n  margin: 0em 0.25em;\n}\ninput.raw_input:focus {\n  box-shadow: none;\n}\np.p-space {\n  margin-bottom: 10px;\n}\ndiv.output_unrecognized {\n  padding: 5px;\n  font-weight: bold;\n  color: red;\n}\ndiv.output_unrecognized a {\n  color: inherit;\n  text-decoration: none;\n}\ndiv.output_unrecognized a:hover {\n  color: inherit;\n  text-decoration: none;\n}\n.rendered_html {\n  color: #000;\n  /* any extras will just be numbers: */\n}\n\n\n\n.rendered_html :link {\n  text-decoration: underline;\n}\n.rendered_html :visited {\n  text-decoration: underline;\n}\n\n\n\n\n\n\n.rendered_html h1:first-child {\n  margin-top: 0.538em;\n}\n.rendered_html h2:first-child {\n  margin-top: 0.636em;\n}\n.rendered_html h3:first-child {\n  margin-top: 0.777em;\n}\n.rendered_html h4:first-child {\n  margin-top: 1em;\n}\n.rendered_html h5:first-child {\n  margin-top: 1em;\n}\n.rendered_html h6:first-child {\n  margin-top: 1em;\n}\n.rendered_html ul:not(.list-inline),\n.rendered_html ol:not(.list-inline) {\n  padding-left: 2em;\n}\n\n\n\n\n\n\n\n\n.rendered_html * + ul {\n  margin-top: 1em;\n}\n.rendered_html * + ol {\n  margin-top: 1em;\n}\n\n\n\n\n\n.rendered_html pre,\n\n\n\n\n.rendered_html tr,\n.rendered_html th,\n\n\n.rendered_html tbody tr:nth-child(odd) {\n  background: #f5f5f5;\n}\n.rendered_html tbody tr:hover {\n  background: rgba(66, 165, 245, 0.2);\n}\n.rendered_html * + table {\n  margin-top: 1em;\n}\n\n.rendered_html * + p {\n  margin-top: 1em;\n}\n\n.rendered_html * + img {\n  margin-top: 1em;\n}\n.rendered_html img,\n\n.rendered_html img.unconfined,\n\n\n.rendered_html * + .alert {\n  margin-top: 1em;\n}\n[dir="rtl"] \ndiv.text_cell {\n  /* Old browsers */\n  display: -webkit-box;\n  -webkit-box-orient: horizontal;\n  -webkit-box-align: stretch;\n  display: -moz-box;\n  -moz-box-orient: horizontal;\n  -moz-box-align: stretch;\n  display: box;\n  box-orient: horizontal;\n  box-align: stretch;\n  /* Modern browsers */\n  display: flex;\n  flex-direction: row;\n  align-items: stretch;\n}\n@media (max-width: 540px) {\n  div.text_cell > div.prompt {\n    display: none;\n  }\n}\ndiv.text_cell_render {\n  /*font-family: "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;*/\n  outline: none;\n  resize: none;\n  width: inherit;\n  border-style: none;\n  padding: 0.5em 0.5em 0.5em 0.4em;\n  color: #000;\n  box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n}\na.anchor-link:link {\n  text-decoration: none;\n  padding: 0px 20px;\n  visibility: hidden;\n}\nh1:hover .anchor-link,\nh2:hover .anchor-link,\nh3:hover .anchor-link,\nh4:hover .anchor-link,\nh5:hover .anchor-link,\nh6:hover .anchor-link {\n  visibility: visible;\n}\n.text_cell.rendered .input_area {\n  display: none;\n}\n.text_cell.rendered \n.text_cell.rendered .rendered_html tr,\n.text_cell.rendered .rendered_html th,\n.text_cell.rendered \n.text_cell.unrendered .text_cell_render {\n  display: none;\n}\n.text_cell .dropzone .input_area {\n  border: 2px dashed #bababa;\n  margin: -1px;\n}\n.cm-header-1,\n.cm-header-2,\n.cm-header-3,\n.cm-header-4,\n.cm-header-5,\n.cm-header-6 {\n  font-weight: bold;\n  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;\n}\n.cm-header-1 {\n  font-size: 185.7%;\n}\n.cm-header-2 {\n  font-size: 157.1%;\n}\n.cm-header-3 {\n  font-size: 128.6%;\n}\n.cm-header-4 {\n  font-size: 110%;\n}\n.cm-header-5 {\n  font-size: 100%;\n  font-style: italic;\n}\n.cm-header-6 {\n  font-size: 100%;\n  font-style: italic;\n}\n</style>\n<style type="text/css"> .highlight pre  .hll { background-color: #ffffcc }\n .highlight pre   { background: #f8f8f8; }\n .highlight pre  .c { color: #408080; font-style: italic } /* Comment */\n .highlight pre  .err { border: 1px solid #FF0000 } /* Error */\n .highlight pre  .k { color: #008000; font-weight: bold } /* Keyword */\n .highlight pre  .o { color: #666666 } /* Operator */\n .highlight pre  .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n .highlight pre  .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n .highlight pre  .cp { color: #BC7A00 } /* Comment.Preproc */\n .highlight pre  .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n .highlight pre  .c1 { color: #408080; font-style: italic } /* Comment.Single */\n .highlight pre  .cs { color: #408080; font-style: italic } /* Comment.Special */\n .highlight pre  .gd { color: #A00000 } /* Generic.Deleted */\n .highlight pre  .ge { font-style: italic } /* Generic.Emph */\n .highlight pre  .gr { color: #FF0000 } /* Generic.Error */\n .highlight pre  .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n .highlight pre  .gi { color: #00A000 } /* Generic.Inserted */\n .highlight pre  .go { color: #888888 } /* Generic.Output */\n .highlight pre  .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n .highlight pre  .gs { font-weight: bold } /* Generic.Strong */\n .highlight pre  .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n .highlight pre  .gt { color: #0044DD } /* Generic.Traceback */\n .highlight pre  .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n .highlight pre  .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n .highlight pre  .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n .highlight pre  .kp { color: #008000 } /* Keyword.Pseudo */\n .highlight pre  .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n .highlight pre  .kt { color: #B00040 } /* Keyword.Type */\n .highlight pre  .m { color: #666666 } /* Literal.Number */\n .highlight pre  .s { color: #BA2121 } /* Literal.String */\n .highlight pre  .na { color: #7D9029 } /* Name.Attribute */\n .highlight pre  .nb { color: #008000 } /* Name.Builtin */\n .highlight pre  .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n .highlight pre  .no { color: #880000 } /* Name.Constant */\n .highlight pre  .nd { color: #AA22FF } /* Name.Decorator */\n .highlight pre  .ni { color: #999999; font-weight: bold } /* Name.Entity */\n .highlight pre  .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n .highlight pre  .nf { color: #0000FF } /* Name.Function */\n .highlight pre  .nl { color: #A0A000 } /* Name.Label */\n .highlight pre  .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n .highlight pre  .nt { color: #008000; font-weight: bold } /* Name.Tag */\n .highlight pre  .nv { color: #19177C } /* Name.Variable */\n .highlight pre  .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n .highlight pre  .w { color: #bbbbbb } /* Text.Whitespace */\n .highlight pre  .mb { color: #666666 } /* Literal.Number.Bin */\n .highlight pre  .mf { color: #666666 } /* Literal.Number.Float */\n .highlight pre  .mh { color: #666666 } /* Literal.Number.Hex */\n .highlight pre  .mi { color: #666666 } /* Literal.Number.Integer */\n .highlight pre  .mo { color: #666666 } /* Literal.Number.Oct */\n .highlight pre  .sa { color: #BA2121 } /* Literal.String.Affix */\n .highlight pre  .sb { color: #BA2121 } /* Literal.String.Backtick */\n .highlight pre  .sc { color: #BA2121 } /* Literal.String.Char */\n .highlight pre  .dl { color: #BA2121 } /* Literal.String.Delimiter */\n .highlight pre  .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n .highlight pre  .s2 { color: #BA2121 } /* Literal.String.Double */\n .highlight pre  .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n .highlight pre  .sh { color: #BA2121 } /* Literal.String.Heredoc */\n .highlight pre  .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n .highlight pre  .sx { color: #008000 } /* Literal.String.Other */\n .highlight pre  .sr { color: #BB6688 } /* Literal.String.Regex */\n .highlight pre  .s1 { color: #BA2121 } /* Literal.String.Single */\n .highlight pre  .ss { color: #19177C } /* Literal.String.Symbol */\n .highlight pre  .bp { color: #008000 } /* Name.Builtin.Pseudo */\n .highlight pre  .fm { color: #0000FF } /* Name.Function.Magic */\n .highlight pre  .vc { color: #19177C } /* Name.Variable.Class */\n .highlight pre  .vg { color: #19177C } /* Name.Variable.Global */\n .highlight pre  .vi { color: #19177C } /* Name.Variable.Instance */\n .highlight pre  .vm { color: #19177C } /* Name.Variable.Magic */\n .highlight pre  .il { color: #666666 } /* Literal.Number.Integer.Long */</style><body><div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">\n</div><div class="inner_cell">\n<div class="text_cell_render border-box-sizing rendered_html">\n<h2 id="0.-&#35013;&#39280;&#22120;">0. &#35013;&#39280;&#22120;<a class="anchor-link" href="#0.-&#35013;&#39280;&#22120;">&#182;</a></h2><p>装饰器:接收一个函数(被装饰的函数)对象,返回一个函数(已装饰的函数)对象。动态的给一个对象添加额外职责,即装饰器设计模式。</p>\n<p>装饰器的典型行为:把被装饰的函数替换为新函数,二者接收的参数相同,并返回被装饰函数本该的返回值,同时增加一些额外操作。</p>\n<p><strong>func = factorial, factorial = clocked</strong></p>\n<p>clock是装饰器</p>\n<p>factorial是被装饰函数</p>\n<p>clocked是被装饰后的函数</p>\n<p>factorial作为func参数传递给装饰器clock,装饰器clock返回clocked函数并复制给factorial。func是clocked的自由变量,两者构成闭包。</p>\n<p>当调用函数factorial时,实际上调用函数locked,而locked函数中func则为被装饰的函数factorial。</p>\n\n</div>\n</div>\n</div>\n<div class="cell border-box-sizing code_cell rendered">\n<div class="input">\n<div class="prompt input_prompt">In&nbsp;[40]:</div>\n<div class="inner_cell">\n    <div class="input_area">\n<div class=" highlight hl-ipython3"><pre><span></span><span class="c1"># 实现一个简单的装饰器:调用被装饰的函数时,打印被调用函数的运行时间,传入参数和输出结果。</span>\n\n<span class="kn">import</span> <span class="nn">time</span>\n\n<span class="k">def</span> <span class="nf">clock</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>\n    <span class="k">def</span> <span class="nf">clocked</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">):</span>\n        <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>\n        <span class="n">result</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>\n        <span class="n">end</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="n">start</span>\n        <span class="n">arg_str</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="nb">repr</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">args</span><span class="p">])</span>\n        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;time: </span><span class="si">{</span><span class="n">end</span><span class="si">}</span><span class="s1">, args: </span><span class="si">{</span><span class="n">arg_str</span><span class="si">}</span><span class="s1">, result: </span><span class="si">{</span><span class="n">result</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>\n        <span class="k">return</span> <span class="n">result</span>\n    <span class="k">return</span> <span class="n">clocked</span>\n    \n<span class="nd">@clock</span>\n<span class="k">def</span> <span class="nf">factorial</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>\n    <span class="k">return</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">n</span> <span class="o">&lt;</span> <span class="mi">2</span> <span class="k">else</span> <span class="n">n</span> <span class="o">*</span> <span class="n">factorial</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>\n</pre></div>\n\n    </div>\n</div>\n</div>\n\n</div>\n<div class="cell border-box-sizing code_cell rendered">\n<div class="input">\n<div class="prompt input_prompt">In&nbsp;[39]:</div>\n<div class="inner_cell">\n    <div class="input_area">\n<div class=" highlight hl-ipython3"><pre><span></span><span class="n">factorial</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>\n</pre></div>\n\n    </div>\n</div>\n</div>\n\n<div class="output_wrapper">\n<div class="output">\n\n\n<div class="output_area">\n\n    <div class="prompt"></div>\n\n\n<div class="output_subarea output_stream output_stdout output_text">\n<pre>time: 7.152557373046875e-07, args: 1, result: 1\ntime: 0.0006625652313232422, args: 2, result: 2\ntime: 0.0007753372192382812, args: 3, result: 6\ntime: 0.0008685588836669922, args: 4, result: 24\ntime: 0.000957489013671875, args: 5, result: 120\ntime: 0.0010552406311035156, args: 6, result: 720\n</pre>\n</div>\n</div>\n\n<div class="output_area">\n\n    <div class="prompt output_prompt">Out[39]:</div>\n\n\n\n\n<div class="output_text output_subarea output_execute_result">\n<pre>720</pre>\n</div>\n\n</div>\n\n</div>\n</div>\n\n</div>\n<div class="cell border-box-sizing code_cell rendered">\n<div class="input">\n<div class="prompt input_prompt">In&nbsp;[42]:</div>\n<div class="inner_cell">\n    <div class="input_area">\n<div class=" highlight hl-ipython3"><pre><span></span><span class="n">factorial</span><span class="o">.</span><span class="vm">__name__</span>  <span class="c1"># 可见factorial是函数locked的引用, 调用factorial(n)即调用locked(n)</span>\n</pre></div>\n\n    </div>\n</div>\n</div>\n\n<div class="output_wrapper">\n<div class="output">\n\n\n<div class="output_area">\n\n    <div class="prompt output_prompt">Out[42]:</div>\n\n\n\n\n<div class="output_text output_subarea output_execute_result">\n<pre>&#39;clocked&#39;</pre>\n</div>\n\n</div>\n\n</div>\n</div>\n\n</div>\n<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">\n</div><div class="inner_cell">\n<div class="text_cell_render border-box-sizing rendered_html">\n<h2 id="1.-&#35013;&#39280;&#22120;&#20309;&#26102;&#36816;&#34892;&#65311;">1. &#35013;&#39280;&#22120;&#20309;&#26102;&#36816;&#34892;&#65311;<a class="anchor-link" href="#1.-&#35013;&#39280;&#22120;&#20309;&#26102;&#36816;&#34892;&#65311;">&#182;</a></h2><p>导入时与运行时:函数装饰器在<strong>导入模块时立即执行</strong>,而被装饰器装饰的函数,只有程序运行时显式调用时才执行。</p>\n<p>装饰器在实际工程中:</p>\n<ul>\n<li><p>通常,装饰器在一个py模块中定义,应用到其他py模块的函数上。</p>\n</li>\n<li><p>通常,装饰器内部绘重新定义一个函数,将其返回。而非作为装饰器参数的函数。</p>\n</li>\n</ul>\n\n</div>\n</div>\n</div>\n<div class="cell border-box-sizing code_cell rendered">\n<div class="input">\n<div class="prompt input_prompt">In&nbsp;[1]:</div>\n<div class="inner_cell">\n    <div class="input_area">\n<div class=" highlight hl-ipython3"><pre><span></span><span class="n">registry</span> <span class="o">=</span> <span class="p">[]</span>\n\n<span class="k">def</span> <span class="nf">register</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>\n    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">&#39;running register </span><span class="si">{</span><span class="n">func</span><span class="si">}</span><span class="s1">&#39;</span><span class="p">)</span>\n    <span class="n">registry</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>\n    <span class="k">return</span> <span class="n">func</span>\n\n<span class="nd">@register</span>\n<span class="k">def</span> <span class="nf">func1</span><span class="p">():</span>\n    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;running func1&#39;</span><span class="p">)</span>\n\n<span class="nd">@register</span>\n<span class="k">def</span> <span class="nf">func2</span><span class="p">():</span>\n    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;running func2&#39;</span><span class="p">)</span>\n    \n<span class="k">def</span> <span class="nf">func3</span><span class="p">():</span>\n    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;running fucn3&#39;</span><span class="p">)</span>\n\n<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>\n    <span class="nb">print</span><span class="p">(</span><span class="n">registry</span><span class="p">)</span>\n    <span class="n">func1</span><span class="p">()</span>\n    <span class="n">func2</span><span class="p">()</span>\n    <span class="n">func3</span><span class="p">()</span>\n</pre></div>\n\n    </div>\n</div>\n</div>\n\n<div class="output_wrapper">\n<div class="output">\n\n\n<div class="output_area">\n\n    <div class="prompt"></div>\n\n\n<div class="output_subarea output_stream output_stdout output_text">\n<pre>running register &lt;function func1 at 0x7fac1e2b6040&gt;\nrunning register &lt;function func2 at 0x7fac1e2b61f0&gt;\n</pre>\n</div>\n</div>\n\n</div>\n</div>\n\n</div>\n<div class="cell border-box-sizing code_cell rendered">\n<div class="input">\n<div class="prompt input_prompt">In&nbsp;[2]:</div>\n<div class="inner_cell">\n    <div class="input_area">\n<div class=" highlight hl-ipython3"><pre><span></span><span class="n">registry</span>\n</pre></div>\n\n    </div>\n</div>\n</div>\n\n<div class="output_wrapper">\n<div class="output">\n\n\n<div class="output_area">\n\n    <div class="prompt output_prompt">Out[2]:</div>\n\n\n\n\n<div class="output_text output_subarea output_execute_result">\n<pre>[&lt;function __main__.func1()&gt;, &lt;function __main__.func2()&gt;]</pre>\n</div>\n\n</div>\n\n</div>\n</div>\n\n</div>\n<div class="cell border-box-sizing code_cell rendered">\n<div class="input">\n<div class="prompt input_prompt">In&nbsp;[4]:</div>\n<div class="inner_cell">\n    <div class="input_area">\n<div class=" highlight hl-ipython3"><pre><span></span><span class="n">main</span><span class="p">()</span>\n</pre></div>\n\n    </div>\n</div>\n</div>\n\n<div class="output_wrapper">\n<div class="output">\n\n\n<div class="output_area">\n\n    <div class="prompt"></div>\n\n\n<div class="output_subarea output_stream output_stdout output_text">\n<pre>[&lt;function func1 at 0x7fac1e2b6040&gt;, &lt;function func2 at 0x7fac1e2b61f0&gt;]\nrunning func1\nrunning func2\nrunning fucn3\n</pre>\n</div>\n</div>\n\n</div>\n</div>\n\n</div>\n<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">\n</div><div class="inner_cell">\n<div class="text_cell_render border-box-sizing rendered_html">\n<h2 id="2.-&#38381;&#21253;">2. &#38381;&#21253;<a class="anchor-link" href="#2.-&#38381;&#21253;">&#182;</a></h2><p>多数装饰器会修改被装饰的函数。通常是在装饰器<strong>内部重新定义一个函数</strong>,将其返回,用来替换被装饰的函数。装饰器内部定义函数几乎都需要<strong>闭包</strong>。</p>\n\n</div>\n</div>\n</div>\n<div class="cell border-box-sizing code_cell rendered">\n<div class="input">\n<div class="prompt input_prompt">In&nbsp;[&nbsp;]:</div>\n<div class="inner_cell">\n    <div class="input_area">\n<div class=" highlight hl-ipython3"><pre><span></span><span class="c1"># 设计某商品收盘均价。注:实时增加新价</span>\n\n<span class="c1"># 类写法</span>\n<span class="k">class</span> <span class="nc">Averager</span><span class="p">():</span>\n    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>\n        <span class="bp">self</span><span class="o">.</span><span class="n">series</span> <span class="o">=</span> <span class="p">[]</span>\n        \n    <span class="k">def</span> <span class="fm">__call__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">price</span><span class="p">):</span>     <span class="c1"># 可调用对象</span>\n        <span class="bp">self</span><span class="o">.</span><span class="n">series</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">price</span><span class="p">)</span>\n        <span class="nb">print</span><span class="p">(</span><span class="nb">sum</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">series</span><span class="p">)</span> <span class="o">/</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">series</span><span class="p">))</span>\n        \n<span class="n">avg</span> <span class="o">=</span> <span class="n">Averager</span><span class="p">()</span>\n<span class="n">avg</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>  <span class="c1"># 可调用对象 __call__()</span>\n<span class="n">avg</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span>\n</pre></div>\n\n    </div>\n</div>\n</div>\n\n</div>\n<div class="cell border-box-sizing code_cell rendered">\n<div class="input">\n<div class="prompt input_prompt">In&nbsp;[14]:</div>\n<div class="inner_cell">\n    <div class="input_area">\n<div class=" highlight hl-ipython3"><pre><span></span><span class="c1"># 函数式写法,高阶函数</span>\n\n<span class="k">def</span> <span class="nf">make_averager</span><span class="p">():</span>\n    <span class="n">series</span> <span class="o">=</span> <span class="p">[]</span>\n    \n    <span class="k">def</span> <span class="nf">averager</span><span class="p">(</span><span class="n">price</span><span class="p">):</span>\n        <span class="n">series</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">price</span><span class="p">)</span>\n        <span class="nb">print</span><span class="p">(</span><span class="nb">sum</span><span class="p">(</span><span class="n">series</span><span class="p">)</span> <span class="o">/</span> <span class="nb">len</span><span class="p">(</span><span class="n">series</span><span class="p">))</span>\n    \n    <span class="k">return</span> <span class="n">averager</span>\n\n<span class="n">avg</span> <span class="o">=</span> <span class="n">make_averager</span><span class="p">()</span>\n<span class="n">avg</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>\n<span class="n">avg</span><span class="p">(</span><span class="mi">11</span><span class="p">)</span>\n</pre></div>\n\n    </div>\n</div>\n</div>\n\n<div class="output_wrapper">\n<div class="output">\n\n\n<div class="output_area">\n\n    <div class="prompt"></div>\n\n\n<div class="output_subarea output_stream output_stdout output_text">\n<pre>10.0\n10.5\n</pre>\n</div>\n</div>\n\n</div>\n</div>\n\n</div>\n<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">\n</div><div class="inner_cell">\n<div class="text_cell_render border-box-sizing rendered_html">\n<p>类写法和函数式写法:</p>\n<ul>\n<li><p>共同之处:通过实例化类Averager()和调用make_averager()都会得到一个<strong>可调用对象</strong>。</p>\n</li>\n<li><p>不同之处:如何存历史值price?类self.series,而函数式则存在series中。</p>\n</li>\n</ul>\n<p>而series作为函数make_averager局部变量,在函数返回时局部变量应该销毁。而series相对于make_averager的内部函数averager称为自由变量。</p>\n\n<pre><code>    series = []\n\n    def averager(price):\n        series.append(price)\n        print(sum(series) / len(series))</code></pre>\n<p>这个代码块称为闭包。闭包是一种函数,它会保留定义函数时存在的自由变量绑定,即使像make_averager函数返回作用域不存在了,averager函数仍然保留使用这些自由变量绑定。</p>\n<p><strong>重点:只有在嵌套函数中的函数,才可能处理不在全局作用域中的外部变量,相对该函数称为自由变量。而该函数与自由变量称为闭包。</strong></p>\n\n</div>\n</div>\n</div>\n<div class="cell border-box-sizing text_cell rendered"><div class="prompt input_prompt">\n</div><div class="inner_cell">\n<div class="text_cell_render border-box-sizing rendered_html">\n<h2 id="3.-&#20851;&#38190;&#23383;nonlocal">3. &#20851;&#38190;&#23383;nonlocal<a class="anchor-link" href="#3.-&#20851;&#38190;&#23383;nonlocal">&#182;</a></h2>\n</div>\n</div>\n</div>\n \n\n</body>\n<script type="text/javascript">if (!document.getElementById(\'mathjaxscript_pelican_#%@#$@#\')) {\n    var mathjaxscript = document.createElement(\'script\');\n    mathjaxscript.id = \'mathjaxscript_pelican_#%@#$@#\';\n    mathjaxscript.type = \'text/javascript\';\n    mathjaxscript.src = \'//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML\';\n    mathjaxscript[(window.opera ? "innerHTML" : "text")] =\n        "MathJax.Hub.Config({" +\n        "    config: [\'MMLorHTML.js\']," +\n        "    TeX: { extensions: [\'AMSmath.js\',\'AMSsymbols.js\',\'noErrors.js\',\'noUndefined.js\'], equationNumbers: { autoNumber: \'AMS\' } }," +\n        "    jax: [\'input/TeX\',\'input/MathML\',\'output/HTML-CSS\']," +\n        "    extensions: [\'tex2jax.js\',\'mml2jax.js\',\'MathMenu.js\',\'MathZoom.js\']," +\n        "    displayAlign: \'center\'," +\n        "    displayIndent: \'0em\'," +\n        "    showMathMenu: true," +\n        "    tex2jax: { " +\n        "        inlineMath: [ [\'$\',\'$\'] ], " +\n        "        displayMath: [ [\'$$\',\'$$\'] ]," +\n        "        processEscapes: true," +\n        "        preview: \'TeX\'," +\n        "    }, " +\n        "    \'HTML-CSS\': { " +\n        " linebreaks: { automatic: true, width: \'95% container\' }, " +\n        "        styles: { \'.MathJax_Display, .MathJax .mo, .MathJax .mi, .MathJax .mn\': {color: \'black ! important\'} }" +\n        "    } " +\n        "}); ";\n    (document.body || document.getElementsByTagName(\'head\')[0]).appendChild(mathjaxscript);\n}\n</script>\n\n            </div>\n            <!-- /.entry-content -->\n        </article>\n    </section>\n\n        </div>\n        <div class="col-sm-3 col-sm-pull-9" id="sidebar">\n            <aside>\n<div id="aboutme">\n    <p>\n      <strong>About Jerry</strong><br/>\n        Jerry Su\n    </p>\n</div><!-- Sidebar -->\n<section class="well well-sm">\n  <ul class="list-group list-group-flush">\n\n<!-- Sidebar/Social -->\n<li class="list-group-item">\n  <h4><i class="fa fa-home fa-lg"></i><span class="icon-label">Social</span></h4>\n  <ul class="list-group" id="social">\n    <li class="list-group-item"><a href="sa517302@mail.ustc.edu.cn"><i class="fa fa-email-square fa-lg"></i> Email</a></li>\n    <li class="list-group-item"><a href="https://github.com/jerrylsu"><i class="fa fa-github-square fa-lg"></i> Github</a></li>\n    <li class="list-group-item"><a href="https://hub.docker.com/u/jerrysu666"><i class="fa fa-docker-square fa-lg"></i> Docker</a></li>\n  </ul>\n</li>\n<!-- End Sidebar/Social -->\n\n<!-- Sidebar/Categories -->\n<li class="list-group-item">\n  <h4><i class="fa fa-home fa-lg"></i><span class="icon-label">Categories</span></h4>\n  <ul class="list-group" id="categories">\n    <li class="list-group-item">\n      <a href="/categories/algorithms.html"><i class="fa fa-folder-open fa-lg"></i>Algorithms</a>\n    </li>\n    <li class="list-group-item">\n      <a href="/categories/english.html"><i class="fa fa-folder-open fa-lg"></i>English</a>\n    </li>\n    <li class="list-group-item">\n      <a href="/categories/miscellanea.html"><i class="fa fa-folder-open fa-lg"></i>Miscellanea</a>\n    </li>\n    <li class="list-group-item">\n      <a href="/categories/ml.html"><i class="fa fa-folder-open fa-lg"></i>ML</a>\n    </li>\n    <li class="list-group-item">\n      <a href="/categories/nlp.html"><i class="fa fa-folder-open fa-lg"></i>NLP</a>\n    </li>\n    <li class="list-group-item">\n      <a href="/categories/programming.html"><i class="fa fa-folder-open fa-lg"></i>Programming</a>\n    </li>\n    <li class="list-group-item">\n      <a href="/categories/pytorch.html"><i class="fa fa-folder-open fa-lg"></i>Pytorch</a>\n    </li>\n    <li class="list-group-item">\n      <a href="/categories/rl.html"><i class="fa fa-folder-open fa-lg"></i>RL</a>\n    </li>\n    <li class="list-group-item">\n      <a href="/categories/tensorflow.html"><i class="fa fa-folder-open fa-lg"></i>TensorFlow</a>\n    </li>\n    <li class="list-group-item">\n      <a href="/categories/tools.html"><i class="fa fa-folder-open fa-lg"></i>Tools</a>\n    </li>\n  </ul>\n</li>\n<!-- End Sidebar/Categories -->\n\n<!-- Sidebar/Tag Cloud -->\n<li class="list-group-item">\n  <a href="/"><h4><i class="fa fa-tags fa-lg"></i><span class="icon-label">Tags</span></h4></a>\n  <ul class="list-group list-inline tagcloud" id="tags">\n    <li class="list-group-item tag-4">\n      <a href="/tags/a.html">A*</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/adaboost.html">Adaboost</a>\n    </li>\n    <li class="list-group-item tag-1">\n      <a href="/tags/algorithm.html">Algorithm</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/attention.html">Attention</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/backtracking.html">BackTracking</a>\n    </li>\n    <li class="list-group-item tag-3">\n      <a href="/tags/bert.html">BERT</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/binary-search.html">Binary Search</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/binary-tree.html">Binary Tree</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/blog.html">Blog</a>\n    </li>\n    <li class="list-group-item tag-3">\n      <a href="/tags/breadth-first-search.html">Breadth First Search</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/c.html">C++</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/cart.html">CART</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/cnn.html">CNN</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/conda.html">Conda</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/cygwin.html">Cygwin</a>\n    </li>\n    <li class="list-group-item tag-1">\n      <a href="/tags/deep-learning.html">Deep Learning</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/docker.html">Docker</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/dynamic-programming.html">Dynamic Programming</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/elmo.html">ELMo</a>\n    </li>\n    <li class="list-group-item tag-2">\n      <a href="/tags/english.html">English</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/featuretools.html">Featuretools</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/flask.html">Flask</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/gbdt.html">GBDT</a>\n    </li>\n    <li class="list-group-item tag-3">\n      <a href="/tags/git.html">Git</a>\n    </li>\n    <li class="list-group-item tag-2">\n      <a href="/tags/hadoop.html">Hadoop</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/hexo.html">Hexo</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/kaggle.html">Kaggle</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/leetcode.html">Leetcode</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/linked-list.html">Linked List</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/linux.html">Linux</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/logistic-regression.html">Logistic Regression</a>\n    </li>\n    <li class="list-group-item tag-1">\n      <a href="/tags/machine-learning.html">Machine Learning</a>\n    </li>\n    <li class="list-group-item tag-1">\n      <a href="/tags/nlp.html">NLP</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/pca.html">PCA</a>\n    </li>\n    <li class="list-group-item tag-1">\n      <a href="/tags/python.html">Python</a>\n    </li>\n    <li class="list-group-item tag-2">\n      <a href="/tags/pytorch.html">Pytorch</a>\n    </li>\n    <li class="list-group-item tag-2">\n      <a href="/tags/rasa.html">RASA</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/regularization.html">Regularization</a>\n    </li>\n    <li class="list-group-item tag-2">\n      <a href="/tags/reinforcement-learning.html">Reinforcement Learning</a>\n    </li>\n    <li class="list-group-item tag-2">\n      <a href="/tags/scala.html">Scala</a>\n    </li>\n    <li class="list-group-item tag-3">\n      <a href="/tags/sorting.html">Sorting</a>\n    </li>\n    <li class="list-group-item tag-2">\n      <a href="/tags/spark.html">Spark</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/sql.html">SQL</a>\n    </li>\n    <li class="list-group-item tag-2">\n      <a href="/tags/tensorflow.html">TensorFlow</a>\n    </li>\n    <li class="list-group-item tag-3">\n      <a href="/tags/tools.html">Tools</a>\n    </li>\n    <li class="list-group-item tag-4">\n      <a href="/tags/vim.html">Vim</a>\n    </li>\n  </ul>\n</li>\n<!-- End Sidebar/Tag Cloud -->\n  </ul>\n</section>\n<!-- End Sidebar -->            </aside>\n        </div>\n    </div>\n</div>\n<!-- End Content Container -->\n\n<footer>\n   <div class="container-fluid">\n      <hr>\n      <div class="row">\n         <div class="col-xs-10">&copy; 2020 Jerry\n            &middot; Powered by <a href="https://github.com/getpelican/pelican-themes/tree/master/pelican-bootstrap3" target="_blank">pelican-bootstrap3</a>,\n            <a href="http://docs.getpelican.com/" target="_blank">Pelican</a>,\n            <a href="http://getbootstrap.com" target="_blank">Bootstrap</a>         </div>\n         <div class="col-xs-2"><p class="pull-right"><i class="fa fa-arrow-up"></i> <a href="#">Back to top</a></p></div>\n      </div>\n   </div>\n</footer>\n<script src="/theme/js/jquery.min.js"></script>\n\n<!-- Include all compiled plugins (below), or include individual files as needed -->\n<script src="/theme/js/bootstrap.min.js"></script>\n\n<!-- Enable responsive features in IE8 with Respond.js (https://github.com/scottjehl/Respond) -->\n<script src="/theme/js/respond.min.js"></script>\n\n\n    <script src="/theme/js/bodypadding.js"></script>\n\n\n</body>\n</html>'
r.status_code
200

Share on: TwitterFacebookEmail

Comments


Related Posts


Reading Time

~17 min read

Published

Category

Programming

Tags

Contact