随手记录第二十话 -- Python3版本虚拟环境安装与AI的接入使用
Python用来写点脚本处理语言简直不要太爽,Python2用了那么久,最近重装了下电脑,自带Python3.9,整好用来接入AI使用一下。
另外用过npm vue项目的也知道每个项目都是不同的node_modules,能完全避免两个项目之间的版本不同问题。现在Python3也有这样的了,叫做虚拟环境,比较厉害的是Python3中的虚拟环境可以多项目共用,使用虚拟环境不仅能确保项目依赖的独立性和稳定性,还能有效避免不同项目之间的依赖冲突,本文将详细介绍 Python3 版本虚拟环境的安装以及 AI 的接入使用方法。
快捷目录
- 1.Python3的安装和虚拟环境配置
- 1.1.Python3 安装
- 1.2.创建虚拟环境
- 1.3.激活虚拟环境
- 1.4.安装所需的库
- 1.5.退出虚拟环境
- 2.在虚拟环境接入AI及其他脚本功能
- 2.1 使用 OpenAI 接入 AI 功能
- 2.2 接口服务提供flask库
- 3.Pyhon窗口应用
- 3.1 依赖引入
- 3.2 图示
- 3.3 代码简示
- 3.4 UI工具
- 3.5 打包
1.Python3的安装和虚拟环境配置
1.1.Python3 安装
前往python官网下载下载3版本,小版本随意。
安装就是无脑双击下一步,如果有add path
字眼可以选择添加一下,mac是自动添加到bin目录的,安装完成后使用下面指令查看版本号,我这是两个版本都有。在命令行(Windows 系统使用命令提示符或 PowerShell,Linux 和 macOS 系统使用终端)中输入以下命令
➜ ~ python -V
Python 2.7.13
➜ ~ python3 -V
Python 3.9.6
如果Windows提示找不到指令 ,可以把安装目录/bin
添加到环境变量path
中即可
1.2.创建虚拟环境
开发者首推工具创建:
如果是开发者首推工具里面创建,我用的是IDEA ,找到右上角设置选择项目配置里面的SDK进行创建:
可以勾选引用全局,这样用的比较多的依赖全局下载好后可以不用重新下载
其他方式推荐shell指令创建:
Python3 自带了创建虚拟环境的工具venv
。在命令行中,进入你希望创建虚拟环境的目录(例如项目文件夹),然后执行以下命令创建一个名为myenv
的虚拟环境(你可以根据需求修改环境名称):
python3 -m venv myenv
命令后,在当前目录下会生成一个名为myenv
的文件夹,里面包含了虚拟环境所需的文件和目录结构。
1.3.激活虚拟环境
- Windows 系统:在命令提示符或 PowerShell 中,进入虚拟环境的Scripts目录,然后运行激活脚本:
myenv\Scripts\activate
- MacOS系统: 打开终端,进行虚拟环境的
bin
目录,然后运行激活脚本:
source python3_venv/bin/activate
同样,激活成功后,命令行提示符会显示虚拟环境名称。
1.4.安装所需的库
激活虚拟环境后,就可以使用pip
直接下载依赖了。例如后面要用到的AI调用库:
pip install openai
通过这种方式安装的库仅存在于当前虚拟环境中,不会影响系统全局的 Python 环境。
1.5.退出虚拟环境
当完成项目开发或不再需要使用虚拟环境时,可以在命令行中输入以下命令退出虚拟环境:
deactivate
2.在虚拟环境接入AI及其他脚本功能
2.1 使用 OpenAI 接入 AI 功能
OpenAI 提供了强大的语言模型 API,通过openai
库,我们可以轻松接入这些模型实现文本生成、对话等功能。首先,你需要在OpenAI官网(其他例如,阿里通义,硅基流动等等)注册账号并获取 API 密钥。
获取 API 密钥后,在 Python 代码中配置密钥并调用 API。以下是一个简单的示例,使用Http和Opeai库来实现调用到Deepseek:
import os
from typing import Dict, Anyimport requests
from openai import OpenAIclass DeepSeekClient:def __init__(self, api_key: str = None, rpc_url: str = None):self.api_key = api_key or os.getenv("DEEPSEEK_API_KEY")self.base_url = rpc_urldef http_request(self, model: str, messages: list) -> Dict[str, Any]:"""直接使用HTTP请求调用DeepSeek API"""headers = {"Content-Type": "application/json","Authorization": f"Bearer {self.api_key}"}payload = {"model": model,"messages": messages}response = requests.post(self.base_url + "/chat/completions", json=payload, headers=headers)return response.json()def openai_request(self, model: str, messages: list) -> Dict[str, Any]:"""使用OpenAI客户端调用DeepSeek API"""client = OpenAI(api_key=self.api_key, base_url=self.base_url)response = client.chat.completions.create(model=model,messages=messages)return response.to_dict()def get_response(self, model: str, messages: list, use_openai_client: bool = False) -> str:"""获取生成结果"""if use_openai_client:result = self.openai_request(model, messages)else:result = self.http_request(model, messages)return result.get("choices", [{}])[0].get("message", {}).get("content", "")# 初始化客户端
client = DeepSeekClient(api_key="xxxxxxxx", rpc_url="https://api.siliconflow.cn/v1")# 使用HTTP直接调用
response_http = client.get_response(model="Qwen/Qwen2.5-Coder-7B-Instruct",messages=[{"role": "user", "content": "你好,你的知识库截止于多久?"}],use_openai_client=False
)
print("http返回:", response_http)# 使用OpenAI客户端调用
response_openai = client.get_response(model="Qwen/Qwen2.5-Coder-7B-Instruct",messages=[{"role": "user", "content": "你好,有什么可以帮助你的吗?"}],use_openai_client=True
)
print("openAi返回:", response_openai)
因为自建的ds几天迁移,改用硅基流动测试了一下,自己填入秘钥即可使用,下面是输出的日志:
http返回: 你好,我的知识库截止到2023年10月。有什么我可以帮你的吗?
openAi返回: 你好!我是一个AI助手,专门帮助回答问题和提供信息。无论是技术、科学、历史还是日常生活中的问题,我都很乐意帮助你。请问你有什么需要了解或讨论的内容吗?
2.2 接口服务提供flask库
这是以前用来做某个服务控制和日志监测实现写的,在这里记录一下
import os
import subprocess
import timeimport flask
from flask import request, make_responseserver = flask.Flask(__name__)
import logginglogger = logging.getLogger()
logger.setLevel(logging.INFO)@server.route('/register', methods=['get', 'post']) # router里面第一个参数,是接口的路径
def reg():# username = request.values.get('username')#这里就是你调用接口的是传入的参数# password = request.values.get('password')#这里就是你调用接口的是传入的参数print(request.json)username = request.json.get("username") # 入参类型是json的话,那么必须得用.json方法才能获取到数据password = request.json.get("password")if username and password:return '{"code":200,"msg":"注册成功!"}'else:return '{"code":938,"msg":"必填参数未填,请看接口文档!"}'@server.route('/login', methods=['POST', 'GET'])
def login():# processInfo = os.popen("ps -ef|grep tset1.py|grep -v grep|awk '{print $2}'").readlines()# if processInfo ==[]:# server.logger.info("进程号为空")# return '{"msg":"进程号为空"}'# if processInfo.__len__() >1:# server.logger.info("存在多个进程,将一一结束")# for i in processInfo:# subprocess.Popen('kill -9 ' + i, shell=True)# server.logger.info("进程结束成功%s"%i)d = {}d["msg"] = "登录成功!!!"server.logger.info("进程结束成功")return "登录成功"# return jsonify(d)n = 0@server.route('/love_you', methods=['POST', 'GET'])
def love_you():resp = make_response('<h1><font color="red">I LOVE YOU~</font></h1>')global nn = n + 1logging.info("请求次数%s" % n)return resp@server.route('/tj_stop')
def stop_python():subprocess.Popen('/root/bin/tj_stop.sh', shell=True)server.logger.info("进程结束成功")return '{"msg":"进程结束成功"}'@server.route('/tj_start')
def start_python():subprocess.Popen('/root/bin/tj_start.sh', shell=True)server.logger.info("进程开始成功")time.sleep(3)return tj_log()@server.route('/tj_log')
def tj_log():processInfo = os.popen("tail -5 /root/logs/tj_start.log").readlines()return '{"msg":"进程开始成功:%s"}' % processInfoif __name__ == "__main__":server.run(port=60000, debug=True, host='0.0.0.0')
启动测试一下,调用http://127.0.0.1:60000/love_you
接口查看下面输出。
好了其他的脚本内容就不去贴了,祝各位读者皆你所爱,也是爱你者。
3.Pyhon窗口应用
有时候脚本内容太多了,很难记得指令了,可以时候就可以用一个窗口应用来实现了。
3.1 依赖引入
安装依赖 用的pyside6 6.9版本
pip install pyside6
打包依赖
pip install pyinstaller
图标问题 要下个依赖 PyInstaller 会自动转换 .ico 到 .icns
pip install pillow
3.2 图示
贴个图,具体功能在代码里看了,不一一说了
3.3 代码简示
import sys
import threading
import timefrom PySide6.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QPlainTextEdit, \QComboBox, QCheckBox, QTableWidget, QTableWidgetItem, QMessageBoxclass MyApp(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):# 设置窗口标题和尺寸self.setWindowTitle("输入框与按钮示例")self.resize(800, 600)# 创建布局管理器(垂直布局)layout = QVBoxLayout()# 创建输入框self.input_box = QLineEdit(placeholderText="请输入内容")layout.addWidget(self.input_box)# 多行文本self.plan_text = QPlainTextEdit(placeholderText="请输入配置")self.plan_text.setMinimumHeight(100)layout.addWidget(self.plan_text)# 水平布局hLayOut = QHBoxLayout()# 下拉框self.combo = QComboBox()self.combo.addItems(["A", "B", "C"])self.combo.currentIndexChanged.connect(self.on_combo_change) # 选项变化时触发hLayOut.addWidget(self.combo)# 复选框self.checkbox = QCheckBox("同意勾选")hLayOut.addWidget(self.checkbox)self.checkbox.stateChanged.connect(lambda s: print("同意勾选状态:", s))layout.addLayout(hLayOut)# 表格self.table = QTableWidget(4, 3)self.table.setHorizontalHeaderLabels(["编号", "姓名", "年龄"]) # 表头#这里需要二元数组self.table.setItem(0,0, QTableWidgetItem("001"))self.table.setItem(0,1, QTableWidgetItem("张三"))self.table.setItem(0,2, QTableWidgetItem("22"))layout.addWidget(self.table)# 创建按钮self.button = QPushButton("提交")layout.addWidget(self.button)self.button.setToolTip("提交吧")# 连接按钮点击信号到槽函数self.button.clicked.connect(self.on_button_click)# 设置窗口布局self.setLayout(layout)def on_button_click(self):if not self.button.isEnabled():returnself.button.setEnabled(False)text = self.input_box.text() # 获取输入框内容print("用户输入:", text)# 可选:清空输入框self.input_box.clear()threading.Thread(target=self.task, args=("线程1", 2)).start()# 弹窗self.qt_alert(text)def task(self, name, delpy):time.sleep(delpy)self.input_box.setText(str(time.time()) + "_" + name)self.button.setEnabled(True)def on_combo_change(self, index):print("当前选择:", self.combo.itemText(index))self.plan_text.setPlainText("当前选择:" + self.combo.itemText(index) + "\n")def qt_alert(self,text):self.msg = QMessageBox()# self.msg.setIcon(QMessageBox.NoIcon)# self.msg.setIcon(QMessageBox.Information)# self.msg.setIcon(QMessageBox.Warning)self.msg.setIcon(QMessageBox.Critical)# self.msg.setIcon(QMessageBox.Question)self.msg.setText("这是 PyQt5 弹窗:"+text)self.msg.setWindowTitle("现代提示")self.msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)result = self.msg.exec_()print(f"用户选择:{result}")if __name__ == "__main__":app = QApplication(sys.argv)window = MyApp()window.show()sys.exit(app.exec_())
3.4 UI工具
绝对UI难画的,可以直接用工具,这个非常推荐,工具是PySide6包内自带的。
路径一搬为enve/lib/python3.9/site-packages/PySide6/Designer.app
,Windows后缀为exe,双击运行就可添加控件了。保存完成后添加到项目中。
代码中使用
def load_ui(self, file_path):"""加载 UI 文件为 QWidget"""loader = QUiLoader()widget = loader.load(file_path)widget.setWindowTitle("自定义对话框")widget.findChild(QPushButton, "pushButton").clicked.connect(self.on_confirm_click)self.widget_log = widget.findChild(QTextEdit, "textEdit")self.widget_log1 = widget.findChild(QListWidget, "listWidget")return widgetdef initUI(self):# 创建主窗口self.setWindowTitle("主窗口")self.resize(400, 300)# 创建主布局main_layout = QVBoxLayout()# 添加按钮触发自定义对话框self.btn = QPushButton("打开自定义对话框")self.btn.clicked.connect(self.show_custom_dialog)main_layout.addWidget(self.btn)# 加载自定义 UI 文件self.custom_dialog = self.load_ui("ui/ces.ui")# 添加到主窗口self.setLayout(main_layout)def show_custom_dialog(self):"""显示自定义对话框"""self.custom_dialog.show()
3.5 打包
pyinstaller --onefile --windowed --icon=logo.ico SimpleGUI.py
需要注意,各个平台只能打各个平台的包,总体来说还是打的很快的。
对于窗口程序,简直是利器,大大的节省排版时间。当然要说窗口UI,还是推荐易语言,好用实用。
以上就是本文的全部内容了,希望以上内容对您有所帮助!
上一篇:随手记录第十九话 – Windows开启远程桌面并穿透-让你如同局域网中一样
下一篇:随手记录第二十一话 – xxxx
春蚕到死丝方尽,蜡炬成灰泪始干。