摘要:首先假設(shè)是一個(gè)包名或者模塊名非對(duì)象名。參數(shù)可以為或者字節(jié)碼對(duì)象,返回。這里可以理解為解釋字節(jié)碼,并將字節(jié)碼執(zhí)行過程中的全局變量存入字典中。
import_string
先來分析一下這個(gè)動(dòng)態(tài)導(dǎo)入函數(shù):werkzeug.utils.import_string
def import_string(import_name, silent=False): """基于字符串動(dòng)態(tài)導(dǎo)入對(duì)象。字符串有兩種形式寫法用點(diǎn)來分割對(duì)象名(``xml.sax.saxutils.escape``)和用冒號(hào)來分割對(duì)象名 (``xml.sax.saxutils:escape``). silent決定發(fā)生異常時(shí)是返回None還是拋出一些異常(安靜,挺形象的。) """ import_name = str(import_name).replace(":", ".") try: try: #首先假設(shè)import_name是一個(gè)包名或者模塊名(非對(duì)象名)。 __import__(import_name) except ImportError: if "." not in import_name: #沒有點(diǎn)說明即使我們假設(shè)錯(cuò)誤,也沒法繼續(xù)嘗試。故而立即拋出異常 raise else: #如果導(dǎo)入正確,那么可以從sys.modules字典里面獲取已經(jīng)導(dǎo)入的模塊或包. #為什么要通過sys.modules[import_name]返回而不是直接return __import__(import_name)呢?因?yàn)開_import__在沒有提供fromlist參數(shù)時(shí),返回值策略為返回第一個(gè)點(diǎn)之前的頂級(jí)包對(duì)象,比如"os.path"返回的是os而不是os.path. return sys.modules[import_name] #如果import_name不是包名或模塊名,而是具體的對(duì)象、函數(shù)名。 module_name, obj_name = import_name.rsplit(".", 1) try: #相當(dāng)于from module_name import obj_name module = __import__(module_name, None, None, [obj_name]) except ImportError: #如果支持的模塊沒有被父模塊設(shè)置好的情形中會(huì)導(dǎo)入失敗,這時(shí)需要先導(dǎo)入父模塊(或包)。典型的例子就是logging與logging.config。 module = import_string(module_name) try: #通過getarr從模塊中返回具體對(duì)象 return getattr(module, obj_name) except AttributeError as e: raise ImportError(e) except ImportError as e: if not silent: reraise( ImportStringError, ImportStringError(import_name, e), sys.exc_info()[2])flask.config模塊
import os import types import errno from werkzeug.utils import import_string from ._compat import string_types, iteritems from . import json class Config(dict): """config類除了正常的dict職責(zé)外,還具有從py文件(模塊)、對(duì)象或字典填充值的能力。 from_envvar會(huì)調(diào)用from_pyfile會(huì)調(diào)用from_object,另還有from_json會(huì)調(diào)用from_mapping 還有一個(gè)便利的get_namespace方法。 """ def __init__(self, root_path, defaults=None): # root_path查找py文件的基路徑。 dict.__init__(self, defaults or {}) self.root_path = root_path def from_envvar(self, variable_name, silent=False): """variable_name是一個(gè)環(huán)境變量名,指向一個(gè)py文件。返回bool值,是否加載填充成功。 """ rv = os.environ.get(variable_name) #...省略部分校驗(yàn)邏輯... #這里調(diào)用from_pyfile return self.from_pyfile(rv, silent=silent) def from_pyfile(self, filename, silent=False): filename = os.path.join(self.root_path, filename) #利用標(biāo)準(zhǔn)庫(kù)types來動(dòng)態(tài)創(chuàng)建一個(gè)模塊對(duì)象,名為config,文件屬性(__file__)指向設(shè)置為前面的filename d = types.ModuleType("config") d.__file__ = filename try: with open(filename) as config_file: #exec,compile都是內(nèi)置函數(shù)。 #exec(object[, globals[, locals]]) 參數(shù)object可以為str或者字節(jié)碼對(duì)象,返回None。這里可以理解為解釋字節(jié)碼,并將字節(jié)碼執(zhí)行過程中的全局變量存入d.__dict__字典中。 #compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1) #compile用于動(dòng)態(tài)編譯文件為字節(jié)碼對(duì)象,其中"exec"為編譯模式,代表整個(gè)文件(多行)編譯,其余模式還有"eval"單行語(yǔ)句編譯,"single"單行交互式語(yǔ)句編譯。 exec(compile(config_file.read(), filename, "exec"), d.__dict__) except IOError as e: ...略pass... #這里調(diào)用from_object,from_object才是關(guān)鍵。 self.from_object(d) return True def from_object(self, obj): """參數(shù)obj可以是str(需要被導(dǎo)入的對(duì)象)或者一個(gè)對(duì)象。它只允許模塊或?qū)ο笾械拇髮憣傩蕴畛溥M(jìn)來,小寫的忽略。 你可以這樣來使用本方法 app.config.from_object("yourapplication.default_config")或者 from yourapplication import default_config app.config.from_object(default_config) """ if isinstance(obj, string_types): obj = import_string(obj) for key in dir(obj): if key.isupper(): #只允許模塊或?qū)ο笾械拇髮憣傩蕴畛溥M(jìn)來,小寫的忽略。 self[key] = getattr(obj, key) def from_json(self, filename, silent=False): """filename是json文件名。這是flask0.11添加的方法。 """ filename = os.path.join(self.root_path, filename) try: with open(filename) as json_file: obj = json.loads(json_file.read()) #注意,如果不知道json.loads的type參數(shù),那么默認(rèn)加載為字典。即obj是一個(gè)字典 except IOError as e: ...略pass... return self.from_mapping(obj) #這里調(diào)用from_mapping def from_mapping(self, *mapping, **kwargs): """行為類似于dict的update方法,只不過忽略小寫屬性.flask0.11添加的方法 """ mappings = [] if len(mapping) == 1: if hasattr(mapping[0], "items"): mappings.append(mapping[0].items()) else: mappings.append(mapping[0]) elif len(mapping) > 1: raise TypeError( "expected at most 1 positional argument, got %d" % len(mapping) ) mappings.append(kwargs.items()) for mapping in mappings: for (key, value) in mapping: if key.isupper(): self[key] = value return True def get_namespace(self, namespace, lowercase=True, trim_namespace=True): """返回一個(gè)字典,這個(gè)字典包含該命名空間的items。這個(gè)命名空間是以_作為分隔標(biāo)識(shí)的.比如 app.config["IMAGE_STORE_TYPE"] = "fs" app.config["IMAGE_STORE_PATH"] = "/var/app/images" app.config["IMAGE_STORE_BASE_URL"] = "http://img.website.com" image_store_config = app.config.get_namespace("IMAGE_STORE_") 結(jié)果 `image_store_config` 會(huì)是這樣:: { "type": "fs", "path": "/var/app/images", "base_url": "http://img.website.com" } 當(dāng)需要利用這個(gè)進(jìn)行傳參時(shí)是比較方便的。 trim_namespace參數(shù)為True時(shí),行為就是上面所述,為False時(shí)返回的key會(huì)包含namespace前綴。 """ rv = {} for k, v in iteritems(self): if not k.startswith(namespace): continue if trim_namespace: key = k[len(namespace):] else: key = k if lowercase: key = key.lower() rv[key] = v return rv def __repr__(self): return "<%s %s>" % (self.__class__.__name__, dict.__repr__(self)) config模塊閱讀配置到此結(jié)束,下一篇主題待定。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/38364.html
摘要:帶附件的郵件有時(shí)候,我們發(fā)郵件的時(shí)候需要添加附件,比如文檔和圖片等,這也很簡(jiǎn)單,代碼如下郵件服務(wù)器地址郵件服務(wù)器端口啟用上面的代碼中,我們通過打開了本機(jī)的某張圖片,然后通過方法將附件內(nèi)容添加到對(duì)象。 前往本文博客 簡(jiǎn)介 給用戶發(fā)送郵件是 Web 應(yīng)用中最常見的任務(wù)之一,比如用戶注冊(cè),找回密碼等。Python 內(nèi)置了一個(gè) smtplib 的模塊,可以用來發(fā)送郵件,這里我們使用 Flask...
原文地址: http://52sox.com/write-a-flask-plugin-for-ueditor/ 近期項(xiàng)目開發(fā)中,隔壁那個(gè)搞python的哥們竟然笑著對(duì)我說,希望我能給他寫1個(gè)百度編輯器的demo,方便他直接調(diào)用。 當(dāng)時(shí)真的受寵若驚,這哥們實(shí)力不在我之下,只能答應(yīng)它了。上網(wǎng)搜索下,有1篇文章Flask項(xiàng)目集成富文本編輯器UEditor實(shí)現(xiàn)圖片上傳功能已經(jīng)有1個(gè)現(xiàn)成的例子了。 這...
原文地址: http://52sox.com/write-a-flask-plugin-for-ueditor/ 近期項(xiàng)目開發(fā)中,隔壁那個(gè)搞python的哥們竟然笑著對(duì)我說,希望我能給他寫1個(gè)百度編輯器的demo,方便他直接調(diào)用。 當(dāng)時(shí)真的受寵若驚,這哥們實(shí)力不在我之下,只能答應(yīng)它了。上網(wǎng)搜索下,有1篇文章Flask項(xiàng)目集成富文本編輯器UEditor實(shí)現(xiàn)圖片上傳功能已經(jīng)有1個(gè)現(xiàn)成的例子了。 這...
摘要:簡(jiǎn)介官網(wǎng)上對(duì)它的定位是一個(gè)微開發(fā)框架。另外一個(gè)必須理解的概念是,簡(jiǎn)單來說就是一套和框架應(yīng)用之間的協(xié)議。功能比較豐富,支持解析自動(dòng)防止攻擊繼承變量過濾器流程邏輯支持代碼邏輯集成等等。那么,從下一篇文章,我們就正式開始源碼之旅了 文章屬于作者原創(chuàng),原文發(fā)布在個(gè)人博客。 flask 簡(jiǎn)介 Flask 官網(wǎng)上對(duì)它的定位是一個(gè)微 python web 開發(fā)框架。 Flask is a micro...
摘要:官方示例第一行類對(duì)象,這個(gè)無需解釋。請(qǐng)求對(duì)象的端點(diǎn)請(qǐng)求視圖函數(shù)的參數(shù)通過源碼的注釋我們可以知道,都只是對(duì)庫(kù)的進(jìn)行了一層包裝并加入一些屬性。接下來會(huì)有更多關(guān)于和相關(guān)文章放出來,敬請(qǐng)期待參考文檔項(xiàng)目源碼版本注釋版 Flask 是一個(gè) Python 實(shí)現(xiàn)的 Web 開發(fā)微框架, 有豐富的生態(tài)資源。本文從一段官方的示例代碼通過一步步打斷點(diǎn)方式解釋 Flask 內(nèi)部的運(yùn)行機(jī)制,在一些關(guān)鍵概念會(huì)...
閱讀 1582·2021-11-25 09:43
閱讀 2486·2019-08-30 15:54
閱讀 2950·2019-08-30 15:53
閱讀 1099·2019-08-30 15:53
閱讀 757·2019-08-30 15:52
閱讀 2546·2019-08-26 13:36
閱讀 818·2019-08-26 12:16
閱讀 1220·2019-08-26 12:13