Directly on the code:
Import Requests Import csv from contextlib Import the closing # saved csv file DEF save_csv (f_name, Data): # 1. Create a file object F = Open (f_name, ' W ' , encoding = ' UTF-. 8 ' , NEWLINE = '' ) # 2. based on the write target file objects built csv csv_writer = csv.writer (F) # 4. SUMMARY csv file is written for Row in Data: csv_writer.writerow (Row) # 5. The close the file f.close () # download csv file def get_pag(): url = '********' # 读取数据 with closing(requests.get(url, stream=True)) as r: f = (line.decode('utf-8') for line in r.iter_lines()) reader = csv.reader(f, delimiter=',', quotechar='"') save_csv(f_name, reader) if __name__ == '__main__': f_name = '123.csv' Reader = get_pag ()
Highlights here:
contextlib.closing the library, studying.
with xxx as conn1:
with yyy as conn2:
code
Really stupid old dog as it can in fact be:
with xxx as conn1, yyy as conn2:
code
from contextlib import closing from urllib2 import urlopen with closing(urlopen('http://www.python.org';)) as page: for line in page: print(line)
First to deny my ideas, where everything will be fine with using, shut down automatically to help me.
class Door(object): def open(self): print 'Door is opened' def close(self): print 'Door is closed' with Door() as d: d.open()
result:
# 报错: Traceback (most recent call last): File "1.py", line 38, in <module> with Door() as d: AttributeError: __exit__
class Door(object): def open(self): print 'Door is opened' def close(self): print 'Door is closed' with contextlib.closing(Door()) as door: door.open()
result:
Door is opened Door is closed
contextlib.closing (xxx), works as follows:
class closing(object): """Context to automatically close something at the end of a block. Code like this: with closing(<module>.open(<arguments>)) as f: <block> is equivalent to this: f = <module>.open(<arguments>) try: <block> finally: f.close() """ def __init__(self, thing): self.thing = thing def __enter__(self): return self.thing def __exit__(self, *exc_info): self.thing.close()
This contextlib.closing () will help it add __enter __ () and __exit __ (), with the condition that it satisfies.
5, is not the only class to enjoy the convenience with you? I'm just a method okay?
Row! Since met contextlib.closing (), it must be recognized under contextlib.contextmanager
This is a decorator, you can make a func () becomes an instance of a class with conditions of ...
! ! ! This FUNC () ... generator must
yield to the first half represents The __enter __ ()
after yield is used to indicate half The __exit __ ()
from contextlib import contextmanager @contextmanager def tag(name): print("<%s>" % name) yield print("</%s>" % name) with tag("h1"): print 'hello world!'
result:
<h1>
hello world!
</h1>
import time def wrapper(func): def new_func(*args, **kwargs): t1 = time.time() ret = func(*args, **kwargs) t2 = time.time() print 'cost time=', (t2-t1) return ret return new_func @wrapper def hello(a,b): time.sleep(1) print 'a + b = ', a+b hello(100,200)
result:
a + b = 300
cost time= 1.00243401527
contextmanger version:
from contextlib import contextmanager @contextmanager def cost_time(): t1 = time.time() yield t2 = time.time() print 'cost time=',t2-t1 with cost_time(): time.sleep(1) a = 100 b = 200 print 'a + b = ', a + b
result:
a + b = 300
cost time= 1.00032901764
Of course, the US point of view it is easy to use decorator ~
This is contextmanager principle:
1, because func () has a generator Well, so run __enter __ () when, contextmanager call self.gen.next () will go to the yield of the func, stopped pending, this have the time.time time = T1 ()
2, and then run with statement statements inside the body, i.e. 300 = B + a
. 3, after running the __exit finish __ () when, ContextManager call self.gen.next ( ) will yield the func from the beginning until the end of the sentence. This time with t2 = time.time (), t2- t1 in order to achieve the effect of statistical cost_time, perfect.
Source:
class GeneratorContextManager(object): """Helper for @contextmanager decorator.""" def __init__(self, gen): self.gen = gen def __enter__(self): try: return self.gen.next() except StopIteration: raise RuntimeError("generator didn't yield") def __exit__(self, type, value, traceback): if type is None: try: self.gen.next() except StopIteration: return else: raise RuntimeError("generator didn't stop") else: if value is None: # Need to force instantiation so we can reliably # tell if we get the same exception back value = type() try: self.gen.throw(type, value, traceback) raise RuntimeError("generator didn't stop after throw()") except StopIteration, exc: return exc is not value except: if sys.exc_info()[1] is not value: raise def contextmanager(func): @wraps(func) def helper(*args, **kwds): return GeneratorContextManager(func(*args, **kwds)) return helper
Thank bloggers ouyangbro 's blog https://blog.csdn.net/emaste_r/article/details/78105713
Thank bloggers big loafers blog of https://blog.csdn.net/t8116189520/article/details/103408560