針對上面的問題, 生成器(Generator)能夠很好的解決。 生成器運算式不會一次將整個清單載入到記憶體之中, 而是生成一個生成器物件(Generator objector), 所以一次只載入一個清單元素。
import time
class demo:
def __init__(self, label):
self.label = label
def __enter__(self):
self.start = time.time()
def __exit__(self, exc_ty, exc_val, exc_tb):
end = time.time()
print('{}: {}'.format(self.label, end - self.start))
with demo('counting'):
n = 10000000
while n > 0:
n -= 1
# counting: 1.36000013351
上下文管理器被with聲明所啟動,這個API涉及到兩個方法。
1. __enter__方法,當執行流進入with代碼塊時,__enter__方法將執行。並且它將返回一個可供上下文使用的物件。
2. 當執行流離開with代碼塊時,__exit__方法被調用,它將清理被使用的資源。
利用@contextmanager裝飾器改寫上面那個例子:
from contextlib import contextmanager
import time
@contextmanager
def demo(label):
start = time.time()
try:
yield
finally:
end = time.time()
print('{}: {}'.format(label, end - start))
with demo('counting'):
n = 10000000
while n > 0:
n -= 1
# counting: 1.32399988174
看上面這個例子,函數中yield之前的所有代碼都類似於上下文管理器中__enter__方法的內容。而yield之後的所有代碼都如__exit__方法的內容。如果執行過程中發生了異常,則會在yield語句觸發。
LazyLoading Properties例子:
import weakref
class lazyattribute(object):
def __init__(self, f):
self.data = weakref.WeakKeyDictionary()
self.f = f
def __get__(self, obj, cls):
if obj not in self.data:
self.data[obj] = self.f(obj)
return self.data[obj]
class Foo(object):
@lazyattribute
def bar(self):
print "Being lazy"
return 42
f = Foo()
print f.bar
# Being lazy
# 42
print f.bar
# 42
class demo(object):
pass
obj = demo()
print "Class of obj is {0}".format(obj.__class__)
print "Class of obj is {0}".format(demo.__class__)
# Class of obj is
# Class of obj is
在上例中,我們定義了一個類demo,並且生成了一個該類的物件obj。首先,可以看到obj的__class__是demo。有意思的來了,那麼demo的class又是什麼呢?可以看到demo的__class__是type。
模式(Patterns)
“請求寬恕比請求許可更容易(EFAP)”
這個Python設計原則是這麼說的“請求寬恕比請求許可更容易(EFAP)”。不提倡深思熟慮的設計思路,這個原則是說應該儘量去嘗試,如果遇到錯誤,則給予妥善的處理。Python有著強大的異常處理機制可以支持這種嘗試,這些機制幫助程式師開發出更為穩定,容錯性更高的程式。
單例
單例是指只能同時存在一個的實例物件。Python提供了很多方法來實現單例。
Null物件
Null物件能夠用來代替None類型以避免對None的測試。
觀察者
觀察者模式允許多個物件訪問同一份資料。
構造函數
構造函數的參數經常被賦值給實例的變數。這種模式能夠用一行代碼替代多個手動設定陳述式。
如有侵權請聯繫小編刪除!!!
import time
class demo:
def __init__(self, label):
self.label = label
def __enter__(self):
self.start = time.time()
def __exit__(self, exc_ty, exc_val, exc_tb):
end = time.time()
print('{}: {}'.format(self.label, end - self.start))
with demo('counting'):
n = 10000000
while n > 0:
n -= 1
# counting: 1.36000013351
上下文管理器被with聲明所啟動,這個API涉及到兩個方法。
1. __enter__方法,當執行流進入with代碼塊時,__enter__方法將執行。並且它將返回一個可供上下文使用的物件。
2. 當執行流離開with代碼塊時,__exit__方法被調用,它將清理被使用的資源。
利用@contextmanager裝飾器改寫上面那個例子:
from contextlib import contextmanager
import time
@contextmanager
def demo(label):
start = time.time()
try:
yield
finally:
end = time.time()
print('{}: {}'.format(label, end - start))
with demo('counting'):
n = 10000000
while n > 0:
n -= 1
# counting: 1.32399988174
看上面這個例子,函數中yield之前的所有代碼都類似於上下文管理器中__enter__方法的內容。而yield之後的所有代碼都如__exit__方法的內容。如果執行過程中發生了異常,則會在yield語句觸發。
LazyLoading Properties例子:
import weakref
class lazyattribute(object):
def __init__(self, f):
self.data = weakref.WeakKeyDictionary()
self.f = f
def __get__(self, obj, cls):
if obj not in self.data:
self.data[obj] = self.f(obj)
return self.data[obj]
class Foo(object):
@lazyattribute
def bar(self):
print "Being lazy"
return 42
f = Foo()
print f.bar
# Being lazy
# 42
print f.bar
# 42
class demo(object):
pass
obj = demo()
print "Class of obj is {0}".format(obj.__class__)
print "Class of obj is {0}".format(demo.__class__)
# Class of obj is
# Class of obj is
在上例中,我們定義了一個類demo,並且生成了一個該類的物件obj。首先,可以看到obj的__class__是demo。有意思的來了,那麼demo的class又是什麼呢?可以看到demo的__class__是type。
模式(Patterns)
“請求寬恕比請求許可更容易(EFAP)”
這個Python設計原則是這麼說的“請求寬恕比請求許可更容易(EFAP)”。不提倡深思熟慮的設計思路,這個原則是說應該儘量去嘗試,如果遇到錯誤,則給予妥善的處理。Python有著強大的異常處理機制可以支持這種嘗試,這些機制幫助程式師開發出更為穩定,容錯性更高的程式。
單例
單例是指只能同時存在一個的實例物件。Python提供了很多方法來實現單例。
Null物件
Null物件能夠用來代替None類型以避免對None的測試。
觀察者
觀察者模式允許多個物件訪問同一份資料。
構造函數
構造函數的參數經常被賦值給實例的變數。這種模式能夠用一行代碼替代多個手動設定陳述式。
如有侵權請聯繫小編刪除!!!