国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > Python > 正文

Python上下文管理器類和上下文管理器裝飾器contextmanager用法實(shí)

2024-09-09 19:02:21
字體:
供稿:網(wǎng)友

本文實(shí)例講述了Python上下文管理器類和上下文管理器裝飾器contextmanager用法。分享給大家供大家參考,具體如下:

一. 什么是上下文管理器

上下文管理器是在Python2.5之后加入的功能,可以在方便的需要的時(shí)候比較精確地分配和釋放資源, with便是上下文管理器的最廣泛的應(yīng)用, 比如:

with open("test/test.txt","w") as f: f.write("hello")

這上會比使用try:...finally:f.close方便的多.

二. 自定義一個(gè)上下文管理器類:

class MyResource:  # __enter__ 返回的對象會被with語句中as后的變量接受  def __enter__(self):    print('connect to resource')    return self  def __exit__(self, exc_type, exc_value, tb):    print('close resource conection')  def query(self):    print('query data')

類中有兩個(gè)特殊的魔術(shù)方法:

__enter__: with語句中的代碼塊執(zhí)行前, 會執(zhí)行__enter__, 返回的值將賦值給with句中as后的變量. __exit__: with語句中的代碼塊執(zhí)行結(jié)束或出錯, 會執(zhí)行_exit__

比如以下代碼:

with Myresource() as r:  r.query()

的打印結(jié)果為:

connect to resource
query data
close resource conection

那么有沒有一個(gè)簡化定義的方法呢, python提供了一個(gè)裝飾器contextmanager

三. 使用contextmanager

from contextlib import contextmanagerclass MyResource:  def query(self):    print('query data')@contextmanagerdef make_myresource():  print('start to connect')  yield MyResource()  print('end connect')  pass

被裝飾器裝飾的函數(shù)分為三部分:

with語句中的代碼塊執(zhí)行前執(zhí)行函數(shù)中yield之前代碼 yield返回的內(nèi)容復(fù)制給as之后的變量 with代碼塊執(zhí)行完畢后執(zhí)行函數(shù)中yield之后的代碼

比如下方代碼:

with make_myresource() as r:   r.query()

的結(jié)果為:

start to connect
query data
end connect

四. 一個(gè)例子, sqlalchemy: 數(shù)據(jù)庫的自動提交和回滾

在編程中如果頻繁的修改數(shù)據(jù)庫, 一味的使用類似try:... except..: rollback() raise e其實(shí)是不太好的.

比如某一段的代碼的是這樣的:

  try:    gift = Gift()    gift.isbn = isbn    ...     db.session.add(gift)    db.session.commit()  except Exception as e:    db.session.rollback()    raise e

為了達(dá)到使用with語句的目的, 我們可以重寫db所屬的類:

from flask_sqlalchemy import SQLAlchemy as _SQLALchemyclass SQLAlchemy(_SQLALchemy):  @contextmanager  def auto_commit(self):    try:      yield      self.session.commit()    except Exception as e:      db.session.rollback()      raise e

這時(shí)候, 在執(zhí)行數(shù)據(jù)的修改的時(shí)候便可以:

 with db.auto_commit():    gift = Gift()    gift.isbn = isbndb.session.add(gift)    db.session.add(gift)with db.auto_commit():  user = User()  user.set_attrs(form.data)  db.session.add(user)

關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python函數(shù)使用技巧總結(jié)》、《Python面向?qū)ο蟪绦蛟O(shè)計(jì)入門與進(jìn)階教程》、《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python字符串操作技巧匯總》、《Python編碼操作技巧總結(jié)》及《Python入門與進(jìn)階經(jīng)典教程》

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 小金县| 隆德县| 钟山县| 涟水县| 陆河县| 孙吴县| 江川县| 松潘县| 台东市| 商南县| 大足县| 大石桥市| 高陵县| 封丘县| 旅游| 蓬莱市| 永定县| 科技| 湟中县| 富阳市| 察隅县| 卢龙县| 巴塘县| 额尔古纳市| 华容县| 开远市| 囊谦县| 台北市| 宁乡县| 玉林市| 三台县| 陈巴尔虎旗| 祁阳县| 平果县| 抚顺市| 榕江县| 醴陵市| 驻马店市| 正宁县| 武清区| 海伦市|