本文相关描述主要是个人的认知和见解,如有不当之处,还望各位大佬指正。
个人其他博客地址:
简书:https://www.jianshu.com/u/d6960089b087
掘金:https://juejin.cn/user/2963939079225608
小钟同学 | 文 【原创】| QQ:308711822
在python通过把字符串映射到实例的变量或者实例的方法,然后进行调用,这种就做反射。
和反射息息相关的一些自身函数:
# -*- coding:utf-8 -*-
class Ape:
# __slots__ = ['name']
def __init__(self, name):
self.name = name
a = Ape('我是你大爷')
# ==========
print(hasattr(a, "say")) # false。因为存在talk方法
print(hasattr(a, "name")) # True。因为存在name变量
# ==========
# 获取对象中的变量的指向的对象的值
n = getattr(a,"name") # 获取name内存对象的的值
print(n)
n = getattr(a,"name2",'没有这个属性') # 获取name内存对象的的值,,没有默认返回
print(n)
# ==========
# 为对象添加方法
def task(self):
print("%s正在交谈"%self.name)
setattr(a,"task",task) # 将task函数添加到对象中p中,并命名为task
a.task(a)
# 为对象添加属性
setattr(a,"age",56) # 将task函数添加到对象中p中,并命名为task
print(a.age)
# ==========
# 删除对象中的变量
delattr(a,"age")
print(a.age) # AttributeError: 'Ape' object has no attribute 'age'
class Ape:
sex = "男"
def __init__(self,name):
pass
@staticmethod
def say(msg=""):
print("开始说话:",msg)
# 获取类Ape 的动态方法并执行
getattr(Ape, "say")(msg="你大爷的") # 666
flask框架自动找到某个模块下相关的属性进行导入:
# 通过模块的属性值来导入---注意是模块 不是__init
def register_nestable_blueprint(app=None,project_name=None,api_name ='api',key_attribute = 'bp',hongtu='hongtu'):
'''
自动的导入的蓝图模块
:param app:
:return:
'''
if not app:
import warnings
warnings.warn('路由注册失败,需要传入Flask对象实例')
return None
if project_name:
# include_packages 这个设置为True很关键,它包含了 检测 对于的_init__内的属性,这个对于外层的遍历的来说很关键
modules = find_modules(f'{project_name}.{api_name}', include_packages=True,recursive=True)
lantu =None
for name in modules:
# print('藍色的合適的話', name)
module = import_string(name)
if hasattr(module, key_attribute):
# print('符合藍圖', name)
# app.register_blueprint(module.mmpbp)
lantu = getattr(module,key_attribute)
app.register_blueprint(getattr(module,key_attribute))
if hasattr(module, hongtu): pass
# print('符合紅土', name)
# getattr(module, hongtu).register(lantu)
else:
import warnings
warnings.warn('路由注册失败,外部项目名称还没定义')
#!/usr/bin/evn python
# coding=utf-8
from flask import Blueprint
bp = Blueprint('sys', __name__, url_prefix='/sys')
import os
import sys
pro_path = os.path.split(os.path.realpath(__file__))[0]
sys.path.append(pro_path)
def auto_register_edprint(edprint_key_attribute ='bp_edprint'):
# 如果存在红图,则自动的导入红图的模块并且进行注册
for root, dirs, files in os.walk(pro_path):
# 遍历所有的文件夹
if len(dirs)<=0:
continue
for d in dirs:
if '__pycache__' not in root and '__pycache__' not in str(d):
pass
# intas = intas+1
# 安装红图对象的执行的次数,等加载到最后的时候再执行操作
install_redprint_index = 0
curr_redprint_dir = os.path.join(root, d)
# 安装当前文件夹是红图的对象名称
for curr_redprint_dir_doot, curr_redprint_dir_dirs, curr_redprint_dir_files in os.walk(curr_redprint_dir):
for curr_redprint_dir_file in curr_redprint_dir_files:
# 查询当前存在红图对象属性的文件
name, ext = os.path.splitext(curr_redprint_dir_file)
# 判断非__init__ 是否存在对应的红图对象模块
if name != '__init__' and ext == '.py':
curr_redprint_module = __import__(d + '.' + name, fromlist=[''])
# module = import_string(name)
# if hasattr(module___sad, 'auto'):
# auto = getattr(module___sad, 'auto')
# 动态的导入模块下某个方法
# auto()
if hasattr(curr_redprint_module, edprint_key_attribute):
# 判断某个属性对象是否存在
cls = getattr(curr_redprint_module, edprint_key_attribute)
# 调用属性的方法
# cls.register2(bp)
install_redprint_index = install_redprint_index + 1
# 避免多次的加载红图对象
if install_redprint_index == len(curr_redprint_dir_files) - 1:
# 当挂载完成所有的红图的路径之后,再执行对应的注册
cls.register(bp)
else:
# 如果__init__ 本身自己就带有了红图的对象属性的话,
if name == '__init__' and ext == '.py':
curr_redprint_module = __import__(d + '.' + name, fromlist=[''])
if hasattr(curr_redprint_module, edprint_key_attribute):
# 判断某个属性对象是否存在
cls = getattr(curr_redprint_module, edprint_key_attribute)
# 当直接的执行注册
cls.register(bp)
pass
def auto_register_lanytu():
# 如果存在红图,则自动的导入红图的模块并且进行注册
for root, dirs, files in os.walk(pro_path):
# 遍历所有的文件夹
if len(dirs)<=0:
continue
for d in dirs:
if '__pycache__' not in root and '__pycache__' not in str(d):
pass
# intas = intas+1
# 安装红图对象的执行的次数,等加载到最后的时候再执行操作
install_redprint_index = 0
curr_redprint_dir = os.path.join(root, d)
# 安装当前文件夹是红图的对象名称
for curr_redprint_dir_doot, curr_redprint_dir_dirs, curr_redprint_dir_files in os.walk(curr_redprint_dir):
for curr_redprint_dir_file in curr_redprint_dir_files:
# 查询当前存在红图对象属性的文件
name, ext = os.path.splitext(curr_redprint_dir_file)
# 判断非__init__ 是否存在对应的红图对象模块
# 如果__init__ 本身自己就带有了红图的对象属性的话,
if name == '__init__' and ext == '.py':
curr_redprint_module = __import__(d + '.' + name, fromlist=[''])
pass
def auto_py():
for root, dirs, files in os.walk(pro_path):
# 导入非文件夹模块的文件
for file in files:
name, ext = os.path.splitext(file)
if ext == '.py' and name != '__init__' and pro_path == root:
__import__(name)
# 如果存在红图,则自动的导入红图的模块并且进行注册
if len(dirs)>0:
pass
break
# 自动注册红图
# auto_register_edprint()
# 自动导入蓝图
auto_py()
# 自动导入蓝图下的红图模块
# auto_register_edprint()
auto_register_lanytu()
纯属个人实践中相关经验阐述总结,如有纰漏,还希望大佬们多多提点!小钟同学 | 文 【原创】| QQ:308711822
原文作者:程序员小钟同学;如有侵权,请联系管理员删除。