前言

目前有一个奇葩的需求, 将某个开源项目整合进自己的项目里去调度, 还需要在每次启动这个开源项目时, 加载不同的配置文件进去, 问题是配置文件并不是一个 conf 或者是其他的什么, 而是以 .py 文件中的变量形式存在, 使用时直接导入的方式去使用, 如图

目录结构



api.py



引用方式

考虑到后期开源项目迭代也需要同步到这里, 而且希望以多线程的方式可同时运行多个该开源项目, 所以更改 .py 不现实

正文

大佬想到了两个方法去做,这里介绍一种

复写 getattr 方法

我们知道, getattr 是一个魔法方法, 在 a.b 时实际上就是找到 a 的 getattr 方法

那我们复写 getattr 方法来完成调用逻辑, 比如动态生成一个字典与该项目绑定, 蛋当调用时我们根据要调用的 key 来返回 value 即可, 但是该项目的引用是 引用其内部的 py 文件配置, 我们只能通过某些方法来将引用覆盖掉, 变成引用到自己设置的 py 文件中

此时我们使用 sys.modules 功能来做, sys.modules 是一个字典, 他在python启动时启动, 我们每导入一个包, 就会在里面留下一条记录, 实际上使用时就在里面去查找获取模块, 其中的自己写的模块是相对路径

于是我们在启动开源项目之前把里面的导入配置模块部分找到, 在外面直接赋值给我们自写的指定文件 即可

在前言里有说, 我们启动开源项目的方式是启动单独的线程去跑, 所以多个线程是多个 配置文件, 此时我们在总调度的这里, 使用 uuid 为每个线程生成一个唯一 id, 在总调度里维护一个字典, key为这个唯一id, value为这个线程分配的keys, 调用getattr时先查询到对应的keys再查找对应的key 即可

复写的 getattr 方法(_key.py)

api = {}

def init_api(uid, keys):  # 初始化字典
value = api.setdefault(uid, {}) # 添加uid对应的keys
for k, v in keys.items():
value[k] = v def __getattr__(name):
uid = current_thread().uid # 获取uuid
return api.get(uid).get(name, '') # 从dict中获取值

在开源项目启动之前替换引用

sys.modules['plug.OneForAll.config.api'] = __import__('_key')  # _key是根目录的 _key.py 文件

在启动线程运行开源项目时赋值 uuid

thread = threading.Thread(target=self.process_func,
# name=func_name,
name=self.taskId,
args=(func_obj, self.domain),
daemon=True)
thread.mod = func_name
thread.uid = uid

import HOOK 功能

这是另一种方式, 通过钩子达到在 import 时执行指定逻辑的方式, 因时间关系这里不多说, 有兴趣的可以自己了解

Python在项目外更改项目内引用的更多相关文章

  1. 引用项目外dll时不显示注释的解决方案

    在引用项目外的dll时,显示类库中的注释可按以下步骤: 方法或变量用summary添加注释,如:         /// <summary>发送post请求         /// < ...

  2. yii2:引用项目外的文件或类

    yii2:引用项目外的文件或类 以项目:frontend为例,文件目录如下: frontend/    frontend/controllers    frontend/views    fronte ...

  3. python项目内import其他内部package的模块的正确方法

    转载 :https://blog.csdn.net/u011089523/article/details/52931844 本文主要介绍如何在一个Python项目中,优雅的实现项目内各个package ...

  4. Eclipse WEB项目更改项目名

    可能很多人都碰到过 WEB 项目需要改名字的事情,不过不是每个人都能很顺畅地完成这个事情.这里简单给大家介绍两种改项目名的方法 1. 在Eclipse 中修改项目名 没错这种方法跟你预料的一样简单,当 ...

  5. python如何发布自已pip项目

    python如何发布自已pip项目前言因为自已平时会把一个常用到逻辑写成一个工具python脚本,像关于时间字符串处理,像关于路径和文件夹遍历什么的工具.每一次新建一个项目的时候都要把这些工具程序复制 ...

  6. 使用NuGet管理项目类库引用

    NuGet 是微软开发平台(包括.NET平台)的一个包管理器,这里只介绍和.NET相关的NuGet Visual Studio扩展客户端, 在VS2010 ,VS2012 ,VS2013中默认集成了N ...

  7. VS问题:该依赖项是由项目系统添加的,不能删除。

    该依赖项是由项目系统添加的,不能删除. 原因:是该项目添加对依赖项的引用时,不是直接引用的dll,而是通过“添加引用->项目”的方式引用的项目. 解决:删除“引用”目录下该依赖项的引用,然后通过 ...

  8. ios项目中引用其他项目复习

    ios项目中引用其他开源项目,今天再次复习了,记个备注. 1. 将开源项目的.xcodeproj拖入项目frameworks 2. Build Phases下 Links Binary With Li ...

  9. ASP.NET项目中引用全局dll

    在ASP.NET项目中,有些dll是全局dll,也就是说,没有放在单个项目的引用中.它们一般存放在如下目录C:\Windows\assembly中 这个时候,我们需要在单个项目中引用他们,应该如何做呢 ...

随机推荐

  1. Scrum 冲刺 第二篇

    Scrum 冲刺 第二篇 每日会议照片 昨天已完成工作 队员 昨日完成任务 黄梓浩 初步完成app项目架构搭建 黄清山 完成部分个人界面模块数据库的接口 邓富荣 完成部分后台首页模块数据库的接口 钟俊 ...

  2. caffe源码 理解链式法则

    网络结构 首先我们抽象理解下一个网络结构是怎样的,如下图所示 F1,F2,F3为某种函数 input为输入数据,output为输出数据 X1,X2为为中间的层的输入输出数据 总体来说有以下关系 X1 ...

  3. P5785 [SDOI2012]任务安排

    本题解用于本蒟蒻加深算法印象,也欢迎大家阅读 本篇题解将分为四块,一步一步地讲解本题, Part 1: O(n^3) \(n^3\) 算法应该非常的显然,我们设 \(f_{i,j}\) 为到 \(i\ ...

  4. 题解-CF1307G Cow and Exercise

    CF1307G Cow and Exercise 给 \(n\) 点 \(m\) 边的带权有向图,边 \(i\) 为 \((u_i,v_i,w_i)\).\(q\) 次询问,每次给 \(x_i\),问 ...

  5. 六、Zookeeper-开源客户端ZkClient与Curator

    ZkClient 从创建会话.创建节点.读取数据.更新数据.删除节点拉介绍ZkClient 添加依赖: pom.xml <dependency> <groupId>com.10 ...

  6. JavaScript:浏览器的本地存储

    cookie.localStorage.sessionStorage的使用 <!DOCTYPE html> <html lang="en"> <hea ...

  7. C++异常之七 标准库里的异常类

    标准库里的异常类 C++标准提供了一组标准异常类,这些类以基类 Exception 开始,标准程序库抛出的所有异常,都派生于该基类,这些类构成如图所示的异常类的派生继承关系,该基类提供一个成员函数 w ...

  8. Linux端口被占用解决

    有时候关闭软件后,后台进程死掉,导致端口被占用.下面以JBoss端口8083被占用为例,列出详细解决过程. 解决方法: 1.查找被占用的端口 netstat -tln netstat -tln | g ...

  9. 处理fMRI数据的一些常用Matlab命令

    背景 处理fMRI数据常常用到MATLAB,在此记录一些常用代码及功能. 1.读取原始DICOM数据 1-1 读入dicom图像并绘图: Image = dicomread('fMRI.dcm'); ...

  10. 开源OLAP引擎对比

    什么是olap 01.绝大多数请求都是读请求 02.数据以相当大的批次(>1000行)更新,而不是单行更新;或者它根本没有更新 03.数据已添加到数据库,但不会进行修改 04.对于读取,每次查询 ...