Python多个项目多个虚拟环境同时调用自己写的工具函数

1.软件环境⚙️

Windows10 教育版64位
Python 3.6.3
Pycharm 2020.1

2.问题描述🔍

相信各位在多年写代码的过程中,肯定都会结合自己所学的专业和项目总结出许多 量身定制 的常用 工具函数 。比如这些函数可以快速对 图像进行预处理 ,有的可以把 任意格式的时间转成标准格式 ,还有的可以 自动生成正则表达式
往往我们会把这些工具函数分别放到多个 .py 文件,然后把这些 .py 文件放在一个叫做 utils 的文件夹中。这样的话,如果有项目需要使用工具函数中的功能就可以直接调用,而不用重复造相同功能的轮子了!
当我们在其他项目中 import utils 时,由于 utils 文件夹和我们的项目文件夹( 图中黄色方框 )是同级的:

例如我这边有2个项目 online learning problematic_map_server_code ,这2个项目下面的 video_atlas_online_learning.py 编译为pyc.py 都需要调用 utils 文件夹下面的工具函数 create_symlink.py ,这时你直接在 video_atlas_online_learning.py 编译为pyc.py 中的任意一个文件中 from utils import create_symlink 都会报错:

ModuleNotFoundError: No module named 'utils'

>> > from utils import create_symlink Traceback ( most recent call last ) : File "<input>" , line 1 , in < module > File "C:\Program Files\JetBrains\PyCharm 2020.1\plugins\python\helpers\pydev\_pydev_bundle\pydev_import_hook.py" , line 21 , in do_import module = self . _system_import ( name , * args , ** kwargs ) ModuleNotFoundError : No module named 'utils'

注意 :如果正在运行的 .py 文件和 utils 是一个层级下的话,是可以成功导入的。

一个笨的办法就是把 utils 函数复制到每个项目中,但这明显太低效了!
再联想一下我们一般通过 pip install xxx 安装的库,都可以直接在项目中使用 import 语句直接调用,但这种方式要么需要把代码上传到 Pypi 或者 Github 自己编译安装到 虚拟环境 中,这种方式以及直接把 工具函数 复制到项目中有以下非常明显的缺点:

  1. 代码传到 Pypi 有一大堆流程有需要走,非常麻烦;
  2. 如果你有多个 虚拟环境 ,那么其实每个 虚拟环境 都需要 pip 安装一遍, 其实相当于你把你的 工具函数 每个环境复制了一次,会形成大量的重复代码,浪费许多空间;
  3. 如果 工具函数 有修改,那么多个 虚拟环境 的都需要修改,相当于维护了多个不同环境的工具函数,异常消耗精力;

那么,有没有什么办法,能让新起的项目直接就能导入这些自己写的 工具函数 呢?就像导入官方模块 import math 一样,不需要安装也不需要复制工具函数到每个项目中,我只需要 import utils 就可以了。

3.解决方法🐡

首先,我们知道 Python 搜索模块的路径(即 sys.path )由如下几部分组成:

  1. 程序的主目录
  2. PYTHONPATH 目录
  3. 标准连接库目录
  4. 任何的 .pth 文件的内容,允许用户任何函数的目录添加到模块搜索路径中

因此,根据上面的提示,有如下方法实现只需要维护 1 工具函数 ,无论这个工具函数在哪里,只要和你的项目在一台电脑上,就可以在任何 项目 ,任何 虚拟环境 中直接导入我们自己写的 工具函数
我这边以 编译为pyc.py 这个文件为例:

from utils import create_symlink

分别验证下述方法,如果运行编译为pyc.py不报错,证明import成功。
utils绝对路径E:\Code\Python\utils

3.1sys.path.append实现项目直接调用工具函数

直接手动在代码里面,通过sys.path添加工具函数文件夹的父文件夹:

import sys
sys.path.append(r'E:\Code\Python')

运行编译为pyc.py,没有报错,证明导入成功,方法可行!
更新:其实不用每个文件都加,可以在Settings-Build,Execution,Deployment-Console-Python Console下的Starting script直接添加工具函数文件夹的父文件夹:
在这里插入图片描述

3.2site-packages文件夹添加.pth文件,实现项目直接调用工具函数

相信很多同学都知道,任何放到site-packages文件夹里面的.py文件或者文件夹,都可以在 Python 中直接导入,我们通过pip install xxx安装的库也是放到这里面。
肯定有同学要问,那是不是把utils文件夹整个复制到site-packages文件夹中呢?
当然不是!因为utils文件夹里面的工具函数代码是在持续演进的,经常会更新里面的代码,如果只是单单放到site-packages里面以后,代码修改起来很不方便。而且,这和直接把utils文件夹复制到项目文件夹中其实根本没有什么区别!
我们要用到的,是Python.pth文件,它可以告诉程序自动添加.pth文件中的路径作为环境变量,然后我们就可以直接导入utils中的函数了:

3.2.1找到site-packages文件夹的路径

直接在你的Python Console或者新建一个.py文件中输入如下代码,查询site-packages文件夹的路径:

>>> import sysconfig
>>> print(sysconfig.get_path('purelib'))
C:\Users\Jayce\Anaconda3\envs\tf2.5\Lib\site-packages

3.2.2在site-packages文件夹中创建.pth文件

site-packages文件夹中,任意文件名创建一个.pth文件,只要不跟已有的模块冲突就行。例如叫做pth_test.pth,然后用任意文本编辑器在其中添加工具函数的父路径即可!例如,本文中就是utils父文件夹绝对路径E:\Code\Python
在这里插入图片描述
运行编译为pyc.py,没有报错,证明导入成功,方法可行!

3.2.3通过对.pth文件创建软连接,实现多个虚拟环境共用一份工具函数

为了在多个虚拟环境中只调用1份工具函数,我们需要在我们的虚拟环境中对上述创建的pth_test.pth生成软连接,这样的话,以后即使工具函数的路径发生了变化,我们只需要修改pth_test.pth中工具函数的路径即可,不同虚拟环境中的软连接会自动应用更改。
例如,我这边在虚拟环境:tf2.5中生成对虚拟环境:tf2.3中的pth_test.pth的软连接:

import os
os.symlink(r'C:\Users\Jayce\Anaconda3\envs\tf2.3\Lib\site-packages\pth_test.pth', r'C:\Users\Jayce\Anaconda3\envs\tf2.5\Lib\site-packages\pth_test.pth')

虚拟环境:tf2.5运行编译为pyc.py,没有报错,证明导入成功,方法可行!如果你有更多的虚拟环境,依次生成软连接即可(不要直接copy软连接,这样复制的是源文件)。

3.3添加 PYTHONPATH环境变量,实现项目直接调用工具函数

通过如下路径:我的电脑 -> 属性 -> 高级系统配置 -> 环境变量 -> 系统变量 新建一个名为 PYTHONPATH的系统环境变量:
在这里插入图片描述
PYTHONPATH直接填入工具函数的父路径即可:
在这里插入图片描述
点击确定保存完毕后,任意打开1CMD,输入下述代码:

echo %PYTHONPATH%

查看PYTHONPATH变量是否添加成功:
在这里插入图片描述
运行编译为pyc.py,没有报错,证明导入成功,方法可行!

  1. CMD一定要新开,不然读取不了你新增的变量;
  2. 如果是Pycharm,需要彻底关闭所有PyCharm窗口后,再次执行代码,才可正常获取环境变量。不然会出现在CMD中可以获取环境变量,PyCharm未正常读取的问题。

3.4解决方法

4.总结🤔

  1. 3.1中的方法需要在每个项目的入口文件中增加两行代码,无法做到全自动,每次我们都要添加,稍微有点麻烦。
  2. 3.2中的方法需要在每个虚拟环境中的site-packages生成软连接,也有点麻烦。
  3. 3.3中的方法只需要添加一个环境变量,简单高效,强烈推荐!!


渣男!都看到这里了,还不赶紧点赞评论收藏走一波?

python可以返回多个值,确实挺方便函数里的return只能返回一个值,但是返回类型是没是限制的因此,我们可以“返回一个 tuple类型,来间接达到返回多个值”。例子是我在robot framework source code 时的例子: 复制代码 代码如下:    def __init__(self, cells):        self.cells, self.comments = self._parse(cells)     def _parse(self, row):        data = []        comments = []        for cell in
我之前完成了一个项目,这开展第二个项目的过程中发现,由于两个项目有一些功能是重复了,所以可以借用第一个项目函数或者模块。那么就有了这个问题,怎么安排多个python项目都用到的函数或者模块?我想到了一下几种可能都解决方案,并且选择了一个适合我自己都方案。 答案: 把共用函数和模块抽取独立出来,组建一个新的第三方模块,这样2个项目都可以调用了。 再问:如何组建第三方模块? 答案:一种就是直接打包发布到pypi,作为共有包,然后其他项目都可以流畅地下载。第二种就是把共有的模块放到一个文件夹,加一个__ini
10.1 PyPi是什么? PyPi 是 Python Package Index 的首字母简,其实表示的是 Python 的 Packag 索引,这个也是 Python 的官方索引。 你需要的包(Package)基本上都可以从这里面找到。作为开源软件,你也希望能够贡献你的 Package 到这里供其他用户使用。我们举个栗子,如果你希望你的 Python 程序能够下载金融数据,目前比较好用的金融数据来源是 Yahoo 和 Google。你可能需要读取这 2 个平台的 API,然后做一个下载部分的代码
在开发 Python 应用时,应用程序经常需要运行在不同版本的环境中、安装不同版本的模块,但是这些模块是相互冲突的、无法共存的。比如,某些 Python 项目运行在 django 2.0 中,而某些 Python 项目运行在 django 3.1 中,我们无法在系统中同时安装两个版本的 django 模块。但是,这是常见需求,很多编程语言都需要面对类似的问题,那要怎么办呢? 在 Python
电脑上出现多个python版本,环境变量配置(包括pip的配置) python环境变量配置(我的电脑有多个python版本,以及多个pip版本,现在通过手工方式配置python环境和pip来区别不同python版本) 配置多个python版本环境变量,能够在cmd中调用不同的python版本 1.当我们下载python会提示我们是否加入path,如果没有选上,那么只有手工添加环境变量。如下图就是选上的 2.如果我们电脑出现多个不同版本的python,那么就有可能出现环境调用出错,明明自己安装了python
不知道有没有小伙伴遇到和我一样的问题,需要在python代码中使用MATLAB代码运行得到的结果,但是如果直接将MATLAB改python,工作量又被加大 那么这时候就需要利用官方给出的方法,在python调用MATLAB 这里可参考官方给出的解决方法 根据自己安装的MATLAB版本去找到对应版本的python 这里以matlab2017a版本为例,对应python3.5 进入MATLAB的安装目录 安装用于 Python 的 MATLAB 引擎 API(最好以管理员身份打开) t.start() 这是一个简单的 Python 多线程函数示例。在这个例子中,我们定义了一个名为 worker 的函数,该函数打印 "Worker"。然后,我们创建了 5 个线程,每个线程都调用 worker 函数,并启动这些线程。 代码中的 threading 模块提供了 Python 中的多线程功能。我们使用 threading.Thread 类来创建线程,并将 worker 函数作为参数传递给该类的构造函数。 注意,如果你想要等待所有线程完成之后再退出程序,可以使用 threading.join() 方法来实现。 ```python # wait for all threads to complete for t in threads: t.join() print("Exiting Main Thread") Pycharm无法添加Conda新建的虚拟环境,点击没反应,在idea.log文件中报错:CondaPythonLegacy - Can‘t find python path to use, will 任博啥时候能毕业?: 那就是你只是付款的时候备注了,但是没有对订单留言。仔细看一下博客"2.获取压缩包密码"这部分哦,你只要留言了,程序自动会发给你的 Pycharm无法添加Conda新建的虚拟环境,点击没反应,在idea.log文件中报错:CondaPythonLegacy - Can‘t find python path to use, will bookgreatc: 我下午4点留言的到现在也没有发呀 Pycharm无法添加Conda新建的虚拟环境,点击没反应,在idea.log文件中报错:CondaPythonLegacy - Can‘t find python path to use, will 任博啥时候能毕业?: vx留言了肯定会发的,不要慌表情包 Pycharm无法添加Conda新建的虚拟环境,点击没反应,在idea.log文件中报错:CondaPythonLegacy - Can‘t find python path to use, will bookgreatc: 刚才留言了,博主貌似没有发呀?急着用表情包 Pycharm无法添加Conda新建的虚拟环境,点击没反应,在idea.log文件中报错:CondaPythonLegacy - Can‘t find python path to use, will 任博啥时候能毕业?: 发了发了,不要急表情包 电脑内存明明还有很多,程序却显示内存不足,报错DefaultCPUAllocator: not enough memory:you tried to allocate 58982400 bytes. python自带的venv创建虚拟环境报错Error: Command returned non-zero exit status 1. Python直接复制已有的venv虚拟环境以创建新的虚拟环境