主要内容
在项目中,多数作用于获取项目配置文件的配置属性。
例如,需要编写一个中间件test,代码如下
class A(object):
def __init__(self, parms):
self.parms = parms
self.print_dicts(**parms)
def print_dicts(self, **parms):
print(parms['NAME'], parms['AGE']) # 打印配置信息
# 类方法(不需要实例化类就可以被类本身调用)
@classmethod
def from_settings(cls, g_dict): # cls : 表示没被实例化的类本身
return cls(g_dict) # 实例化
类方法 from_settings用于获取配置文件的配置信息
中间件需要获取settings文件的配置属性,settings.py代码如下:
# 注册中间件
DICTS = [
'test.A'
]
NAME = 'YangJiHai' # 全局配置变量
AGE = '20'
# settings文件与中间件交互的处理,为了简便代码放在这里演示
for test in DICTS:
m, c = test.rsplit('.', 1) # 反向分割取得类名
m = __import__(m) # 导入模块
if hasattr(m, c): # 判断模块中是否存在该字符串属性
target_class = getattr(m, c) # 获取该属性的引用
if hasattr(target_class, 'from_settings'): # 获取inp的引用
target_func = getattr(target_class, 'from_settings')
g = globals() # 获取全局变量返回字典类型
target_func(g) # 执行
知识点
- rsplit-反向分割字符串 split
- __ import__() 函数用于动态加载类和函数
- 反射机制 hasattr()、getattr()
- globals() 获取全局变量返回字典类型
最终会调用print_dicts打印配置信息
知识补充
拿python 爬虫框架Scrapy举例,如果使用过该框架,查看源码可以发现基本也是类似这样的思路
scrapy.middleware.py
class MiddlewareManager(object):
"""Base class for implementing middleware managers"""
component_name = 'foo middleware'
def __init__(self, *middlewares):
self.middlewares = middlewares
self.methods = defaultdict(list)
for mw in middlewares:
self._add_middleware(mw)
@classmethod
def _get_mwlist_from_settings(cls, settings):
raise NotImplementedError
@classmethod
def from_settings(cls, settings, crawler=None):
mwlist = cls._get_mwlist_from_settings(settings)
middlewares = []
enabled = []
for clspath in mwlist:
try:
mwcls = load_object(clspath)
if crawler and hasattr(mwcls, 'from_crawler'):
mw = mwcls.from_crawler(crawler)
elif hasattr(mwcls, 'from_settings'):
mw = mwcls.from_settings(settings)
else:
mw = mwcls()
middlewares.append(mw)
enabled.append(clspath)
except NotConfigured as e:
if e.args:
clsname = clspath.split('.')[-1]
logger.warning("Disabled %(clsname)s: %(eargs)s",
{'clsname': clsname, 'eargs': e.args[0]},
extra={'crawler': crawler})
logger.info("Enabled %(componentname)ss:\n%(enabledlist)s",
{'componentname': cls.component_name,
'enabledlist': pprint.pformat(enabled)},
extra={'crawler': crawler})
return cls(*middlewares)
@classmethod
def from_crawler(cls, crawler):
return cls.from_settings(crawler.settings, crawler)