裝飾器模式(Decorator Pattern)容許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是做爲現有的類的一個包裝。 python
這種模式建立了一個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。 express
軟件實體應該是可擴展,而不可修改的。也就是說,對擴展是開放的,而對修改是封閉的,具體能夠參考: 編程
百度百科: https://baike.baidu.com/item/開放封閉原則/6028662?fr=aladdin 設計模式
維基百科: https://zh.wikipedia.org/wiki/開閉原則 數組
在電腦程序設計中,做用域(scope,或譯做有效範圍)是名字(name)與實體(entity)的綁定(binding)保持有效的那部分計算機程序。不一樣的編程語言可能有不一樣的做用域和名字解析。而同一語言內也可能存在多種做用域,隨實體的類型變化而不一樣。做用域類別影響變量的綁定方式,根據語言使用靜態做用域仍是動態做用域變量的取值可能會有不一樣的結果。 閉包
出自維基百科: https://zh.wikipedia.org/wiki/做用域 less
在Python中,只有模塊(module),類(class)以及函數(def、lambda)纔會引入新的做用域,其它的代碼塊(如if、try、for等)是不會引入新的做用域的. 編程語言
來自: http://www.cnblogs.com/yuanchenqi/articles/5828233.html ide
即:L-R-G-B
local: 局部做用域,即函數中定義的變量
enclosing: 嵌套的父級函數的局部做用域,即包含此函數的上級函數的局部做用域,但不是全局的
global:全局變量,就是模塊級別定義的變量
builtins: 內置做用域(python內置)
LEGB含義解釋: L-Local(function);函數內的名字空間 E-Enclosing function locals;外部嵌套函數的名字空間(例如closure) G-Global(module);函數定義所在模塊(文件)的名字空間 B-Builtin(Python);Python內置模塊的名字空間 LEGB規定了查找一個名稱的順序爲:local-->enclosing function locals-->global-->builtin
做者:_Zhao_ 連接:http://www.jianshu.com/p/3b72ba5a209c 來源:簡書 |
下面內容來自Python的官方文檔: 4.2.2. Resolution of names A scope defines the visibility of a name within a block. If a local variable is defined in a block, its scope includes that block. If the definition occurs in a function block, the scope extends to any blocks contained within the defining one, unless a contained block introduces a different binding for the name. When a name is used in a code block, it is resolved using the nearest enclosing scope. The set of all such scopes visible to a code block is called the block's environment. When a name is not found at all, a NameError exception is raised. If the current scope is a function scope, and the name refers to a local variable that has not yet been bound to a value at the point where the name is used, an UnboundLocalError exception is raised. UnboundLocalError is a subclass of NameError. If a name binding operation occurs anywhere within a code block, all uses of the name within the block are treated as references to the current block. This can lead to errors when a name is used within a block before it is bound. This rule is subtle. Python lacks declarations and allows name binding operations to occur anywhere within a code block. The local variables of a code block can be determined by scanning the entire text of the block for name binding operations. If the global statement occurs within a block, all uses of the name specified in the statement refer to the binding of that name in the top-level namespace. Names are resolved in the top-level namespace by searching the global namespace, i.e. the namespace of the module containing the code block, and the builtins namespace, the namespace of the module builtins. The global namespace is searched first. If the name is not found there, the builtins namespace is searched. The global statement must precede all uses of the name. The global statement has the same scope as a name binding operation in the same block. If the nearest enclosing scope for a free variable contains a global statement, the free variable is treated as a global. The nonlocal statement causes corresponding names to refer to previously bound variables in the nearest enclosing function scope. SyntaxError is raised at compile time if the given name does not exist in any enclosing function scope. The namespace for a module is automatically created the first time a module is imported. The main module for a script is always called __main__. Class definition blocks and arguments to exec() and eval() are special in the context of name resolution. A class definition is an executable statement that may use and define names. These references follow the normal rules for name resolution with an exception that unbound local variables are looked up in the global namespace. The namespace of the class definition becomes the attribute dictionary of the class. The scope of names defined in a class block is limited to the class block; it does not extend to the code blocks of methods – this includes comprehensions and generator expressions since they are implemented using a function scope. This means that the following will fail: class A: a = 42 b = list(a + i for i in range(10)) |
在計算機科學中,閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函數閉包(function closures),是引用了自由變量的函數。這個被引用的自由變量將和這個函數一同存在,即便已經離開了創造它的環境也不例外。因此,有另外一種說法認爲閉包是由函數和與其相關的引用環境組合而成的實體。閉包在運行時能夠有多個實例,不一樣的引用環境和相同的函數組合能夠產生不一樣的實例。
出自維基百科: https://zh.wikipedia.org/wiki/閉包_(計算機科學)
閉包=函數塊+定義函數時的環境
In [15]: def outer(): ...: name ="Tom" ...: def inner(): ...: return name ...: return inner ...:
In [16]: ret = outer()
In [17]: ret Out[17]: <function __main__.outer.<locals>.inner>
In [18]: ret() Out[18]: 'Tom' |
如圖:out()內部空間的name在外部被使用了.嗯,這就是個閉包:
還有疑問能夠移步到: http://www.cnblogs.com/yuanchenqi/articles/5830025.html
一開始介紹了什麼是裝飾器,以及爲何要用裝飾器,那麼怎麼去實現一個裝飾器,以及裝飾器是怎麼工做的:
例如.如今有一個函數,如今須要在這個函數上新加一些功能:
import time def foo(): print("hello world") time.sleep(2) # 如今要輸出foo()實際的執行時間能夠這樣 def show_time(): start=time.time() foo() end=time.time() print(end-start)
# 執行變成了 show_time() # show_time() |
||||
def show_time1(f): """將函數做爲參數傳入""" start = time.time() f() end = time.time() print(end - start) show_time1(foo) |
||||
def show_time(f): def inner(): start = time.time() f() end=time.time() print(end-start) return inner foo = show_time(foo) foo() |
||||
# python提供了一種方法 @show_time #至關於執行了foo = show_time(foo) def foo(): print("hello world") time.sleep(2)
foo() |
||||
執行foo()實際上至關於執行的是inner()
這時inner()就是一個閉包 |
||||
當foo存在參數的時候如何處理:注意看上圖,圖中foo實際上即便inner
|
||||
忽然有個想法,裝飾器上還可不能夠再加裝飾器: 答案是能夠滴: import time
def show_time(f): def inner(*args,**kwargs): start = time.time() f(*args,**kwargs) end=time.time() print(end-start) return inner
def test(f): def inner(): print("test") f() return inner @test @show_time #至關於執行了foo = show_time(foo) def foo(): """foo有參數的狀況""" print("foo") time.sleep(2) foo() |
||||
Now 給裝飾器加一個參數.
|