Python函数(11自定义模块第三方模块内置模块)

news2024/11/15 8:26:38

   Python基础语法文章导航:

  1. Python基础(01初识数据类型&变量)
  2. Python基础(02条件&循环语句)
  3. Python基础(03字符串格式化&运算符&进制&编码)
  4. Python基础(04 基础练习题)
  5. Python数据类型(day05整型&布尔类型&字符串类型)
  6. Python数据类型(06列表&元组)
  7. Python数据类型(07集合&字典&浮点型&None)
  8. Python文件操作01(自动化测试文件相关操作)
  9. Python函数入门(08函数定义&参数&返回值)

  10. Python文件操作02(自动化测试文件相关操作)

  11. Python函数(10生成器&内置函数&推导式)

目录

前言

一.自定义模块

1.模块和包

2.导入

(1)导入的本质

(2)导入方法一,import xxxx:

(3)导入方法二,from xxxx import xxx:

3.相对导入,需要有包名称

4.导入别名,as

5.主文件

二.第三方模块

三.内置模块

1.os

2.shutil

3.sys

4.random

5.hashlib

6.configparser

7.xml

8.json

(1)JSON格式的作用

(2)Python数据类型与json格式的相互转换:

(a)数据类型 -> json ,一般称为:序列化

(b)json格式 -> 数据类型,一般称为:反序列化

(3)类型要求

(4)其他功能

总结:


前言

        本文主要是讲解函数模块的一些知识。

一.自定义模块

1.模块和包

        在开发简单的程序时,使用一个py文件就可以搞定,如果程序比较庞大,为了代码结构清晰,开发人员之间的分工,会将功能按照某种规则拆分到不同的py文件中,使用时再进行导入即可。或者,当其他的项目需要导入该项目的某些功能模块的时候,也可以进行导入,这样就极大的减少了代码的重复性,增加了可复用性。

在Python中一般对文件和文件的称呼(很多开发者的平时开发中也有人都称为模块)

  • 一个py文件,模块(module)。

  • 含多个py文件的文件夹,包(package)。

注意:在包(文件夹)中有一个默认内容为空的__init__.py的文件,一般用于描述当前包的信息(在导入他下面的模块时,也会自动加载)。

  • py2必须有,如果没有导入包就会失败。

  • py3可有可无。

2.导入

(1)导入的本质

        将某个文件中的内容先加载到内存中,然后再去内存中拿过来使用。

(2)导入方法一,import xxxx:

        import xxxx(一般多用于导入sys.path目录下的一个py文件),例如文件(模块)级别如下,如何在run.py文件中导入各py模块文件:

文件级别,导入文件的路径到最后一层文件::

├── commons
│   ├── __init__.py
│   ├── convert.py
│   ├── page.py
│   ├── tencent
│   │   ├── __init__.py
│   │   ├── sms.py
│   │   └── wechat.py
│   └── utils.py
├── many.py
└── run.py

包级别,导入包的路径到最后一层包文件:

├── commons
│   ├── __init__.py
│   ├── convert.py
│   ├── page.py
│   └── utils.py
├── third
│   ├── __init__.py
│   ├── ali
│   │   └── oss.py
│   └── tencent
│       ├── __init__.py
│       ├── __pycache__
│       ├── sms.py
│       └── wechat.py
└── run.py

(3)导入方法二,from xxxx import xxx:

        from xxxx import xxx【常用】,一般适用于多层嵌套和导入模块中某个成员的情况。

成员级别,from   导入文件路径到模块级别(py)  import      该py文件里面的函数

 |── commons
│   ├── __init__.py
│   ├── convert.py
│   ├── page.py
│   └── utils.py
├── many.py
└── run.py

        提示:基于from模式也可以支持 from many import *,即:导入一个模块中所有的成员(可能会重名,所以用的少)。

模块级别,from    导入文件路径到包级别     import     对应py文件名字

├── commons
│   ├── __init__.py
│   ├── convert.py
│   ├── page.py
│   └── utils.py
├── many.py
└── run.py

包级别,from    外层包名     import     最里一层包名::

├── commons
│   ├── __init__.py
│   ├── convert.py
│   ├── page.py
│   ├── tencent
│   │   ├── __init__.py
│   │   ├── sms.py
│   │   └── wechat.py
│   └── utils.py
├── many.py
└── run.py

3.相对导入,需要有包名称

        from xxxx import xxx也支持相对导入:from  同文件目录下模块名py文件或上级文件目录下模块名py文件   import   模块中的方法,示例如下

相对导入只能用在包中的py文件中(即:嵌套在文件中的py文件才可以使用,项目根目录下无法使用)。

4.导入别名,as

        如果项目中导入 成员/模块/包 有重名,那么后导入的会覆盖之前导入,为了避免这种情况的发生,Python支持重命名,即:

from xxx.xxx import xx as xo
import x1.x2 as pg

有了as的存在,让import  xx.xxx.xxxx在调用执行时,会变得更加简单

原来:

import commons.page
v1=commons.page.pagination()

现在:

import commons.page as pg
v1 = pg.pagination()

5.主文件

        主文件,其实就是在程序执行的入口文件,例如:

├── commons
│   ├── __init__.py
│   ├── convert.py
│   ├── page.py
│   ├── tencent
│   │   ├── __init__.py
│   │   ├── sms.py
│   │   └── wechat.py
│   └── utils.py
├── many.py
└── run.py

        通常是执行 run.py 去运行程序,其他的py文件都是一些功能代码。当我们去执行一个文件时,文件内部的 __name__变量的值为 __main__,所以,主文件经常会看到:

import many
from commons import page
from commons import utils
def start():
    v1 = many.show()
    v2 = page.pagination()
    v3 = utils.encrypt()

if __name__ == '__main__':
    start()

        只有是以主文件的形式运行此脚本时start函数才会执行,被导入时则不会被执行。

二.第三方模块

        第三方模块(用别人写好并开源出来的py代码 )必须要先安装才可以使用。

1.只需要在自己终端执行:   pip3 install 模块名称

2.如要指定版本则可以通过:pip3 install 模块名称==版本

3.pip想要升级为最新的版本例如:..../Versions/3.9/bin/python3.9 -m pip install --upgrade pip

4.pip默认是去 https://pypi.org 去下载第三方模块(本质上就是别人写好的py代码),国外的网站速度会比较慢,为了加速可以使用国内的豆瓣源。

一次性使用:pip3.9 install 模块名称  -i  https://pypi.douban.com/simple/

永久使用:

        配置:

# 在终端执行如下命令
pip3.9 config set global.index-url https://pypi.douban.com/simple/

# 执行完成后,提示在我的本地文件中写入了豆瓣源,以后再通过pip去安装第三方模块时,就会默认使用豆瓣源了。
# 自己以后也可以打开文件直接修改源地址。
Writing to /Users/wupeiqi/.config/pip/pip.conf


#再进行下载
pip3.9 install 模块名称

5.也可以有其他的下载源进行使用:

        阿里云:http://mirrors.aliyun.com/pypi/simple/
        中国科技大学:https://pypi.mirrors.ustc.edu.cn/simple/ 
        清华大学:https://pypi.tuna.tsinghua.edu.cn/simple/
        中国科学技术大学:http://pypi.mirrors.ustc.edu.cn/simple/

三.内置模块

1.os

import os

# 1. 获取当前脚本绝对路径
"""
abs_path = os.path.abspath(__file__)
print(abs_path)
"""

# 2. 获取当前文件的上级目录
"""
base_path = os.path.dirname( os.path.dirname(路径))
print(base_path)
"""

# 3. 路径拼接
"""
p1 = os.path.join(base_path, 'xx')
print(p1)

p2 = os.path.join(base_path, 'xx', 'oo', 'a1.png')
print(p2)
"""

# 4. 判断路径是否存在
"""
exists = os.path.exists(p1)
print(exists)
"""

# 5. 创建文件夹
"""
os.makedirs(路径)
"""
"""
path = os.path.join(base_path, 'xx', 'oo', 'uuuu')
if not os.path.exists(path):
    os.makedirs(path)
"""

# 6. 是否是文件夹
"""
file_path = os.path.join(base_path, 'xx', 'oo', 'uuuu.png')
is_dir = os.path.isdir(file_path)
print(is_dir) # False

folder_path = os.path.join(base_path, 'xx', 'oo', 'uuuu')
is_dir = os.path.isdir(folder_path)
print(is_dir) # True

"""

# 7. 删除文件或文件夹
"""
os.remove("文件路径")
"""
"""
path = os.path.join(base_path, 'xx')
shutil.rmtree(path)
"""
  • listdir,查看目录下所有的文件

  • walk,查看目录下所有的文件(含子孙文件)

    import os
    
    """
    data = os.listdir("/Users/wupeiqi/PycharmProjects/luffyCourse/day14/commons")
    print(data)
    # ['convert.py', '__init__.py', 'page.py', '__pycache__', 'utils.py', 'tencent']
    """
    
    """
    要遍历一个文件夹下的所有文件,例如:遍历文件夹下的所有mp4文件
    """
    data = os.walk("/Users/wupeiqi/Documents/视频教程/路飞Python/mp4")
    for path, folder_list, file_list in data:
        for file_name in file_list:
            file_abs_path = os.path.join(path, file_name)
            ext = file_abs_path.rsplit(".",1)[-1]
            if ext == "mp4":
                print(file_abs_path)
    

2.shutil

import shutil

# 1. 删除文件夹
"""
path = os.path.join(base_path, 'xx')
shutil.rmtree(path)
"""

# 2. 拷贝文件夹
"""
shutil.copytree("/Users/wupeiqi/Desktop/图/csdn/","/Users/wupeiqi/PycharmProjects/CodeRepository/files")
"""

# 3.拷贝文件
"""
shutil.copy("/Users/wupeiqi/Desktop/图/csdn/WX20201123-112406@2x.png","/Users/wupeiqi/PycharmProjects/CodeRepository/")
shutil.copy("/Users/wupeiqi/Desktop/图/csdn/WX20201123-112406@2x.png","/Users/wupeiqi/PycharmProjects/CodeRepository/x.png")
"""

# 4.文件或文件夹重命名
"""
shutil.move("/Users/wupeiqi/PycharmProjects/CodeRepository/x.png","/Users/wupeiqi/PycharmProjects/CodeRepository/xxxx.png")
shutil.move("/Users/wupeiqi/PycharmProjects/CodeRepository/files","/Users/wupeiqi/PycharmProjects/CodeRepository/images")
"""

# 5. 压缩文件
"""
# base_name,压缩后的压缩包文件
# format,压缩的格式,例如:"zip", "tar", "gztar", "bztar", or "xztar".
# root_dir,要压缩的文件夹路径
"""
# shutil.make_archive(base_name=r'datafile',format='zip',root_dir=r'files')


# 6. 解压文件
"""
# filename,要解压的压缩包文件
# extract_dir,解压的路径
# format,压缩文件格式
"""
# shutil.unpack_archive(filename=r'datafile.zip', extract_dir=r'xxxxxx/xo', format='zip')

3.sys

import sys

# 1. 获取解释器版本
"""
print(sys.version)
print(sys.version_info)
print(sys.version_info.major, sys.version_info.minor, sys.version_info.micro)
"""

# 2. 导入模块路径
"""
print(sys.path)
"""
  • argv,执行脚本时,python解释器后面传入的参数

import sys

print(sys.argv)


# [
#       '/Users/wupeiqi/PycharmProjects/luffyCourse/day14/2.接受执行脚本的参数.py'
# ]

# [
#     "2.接受执行脚本的参数.py"
# ]

# ['2.接受执行脚本的参数.py', '127', '999', '666', 'wupeiqi']

# 例如,请实现下载图片的一个工具。

def download_image(url):
    print("下载图片", url)


def run():
    # 接受用户传入的参数
    url_list = sys.argv[1:]
    for url in url_list:
        download_image(url)


if __name__ == '__main__':
    run()

4.random

import random

# 1. 获取范围内的随机整数
v = random.randint(10, 20)
print(v)

# 2. 获取范围内的随机小数
v = random.uniform(1, 10)
print(v)

# 3. 随机抽取一个元素
v = random.choice([11, 22, 33, 44, 55])
print(v)

# 4. 随机抽取多个元素
v = random.sample([11, 22, 33, 44, 55], 3)
print(v)

# 5. 打乱顺序
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]
random.shuffle(data)
print(data)

5.hashlib

        hashlib 是 Python 标准库中的一个模块,用于提供各种安全哈希和消息摘要算法。这个模块可以用来创建哈希对象,通过这些对象可以生成文件或数据块的哈希值,常用于数据的完整性验证和密码学应用。

import hashlib
#hashlib.md5()、hashlib.sha256() 创建了 MD5 和 SHA-256 的哈希对象
hash_object = hashlib.md5()
hash_object.update("武沛齐".encode('utf-8'))
result = hash_object.hexdigest()
print(result)
#17351012472429d52d0c0d23d468173d
import hashlib

hash_object = hashlib.md5("iajfsdunjaksdjfasdfasdf".encode('utf-8'))
hash_object.update("武沛齐".encode('utf-8'))
result = hash_object.hexdigest()
print(result)
#ff533a063c4ae507be583841e6576829

6.configparser

见Python文件操作02(自动化测试文件相关操作)Python文件操作01(自动化测试文件相关操作)Python文件操作02(自动化测试文件相关操作)中的XML内容

7.xml

见Python文件操作02(自动化测试文件相关操作)中的XML内容

8.json

        json模块,是python内部的一个模块,可以将python的数据格式 转换为json格式的数据,也可以将json格式的数据转换为python的数据格式。

json格式,是一个数据格式(本质上就是个字符串,常用语网络数据传输)

# Python中的数据类型的格式
data = [
    {"id": 1, "name": "武沛齐", "age": 18},
    {"id": 2, "name": "alex", "age": 18},
    ('wupeiqi',123),
]

# JSON格式
value = '[{"id": 1, "name": "武沛齐", "age": 18}, {"id": 2, "name": "alex", "age": 18},["wupeiqi",123]]'

(1)JSON格式的作用

跨语言数据传输,例如:
    A系统用Python开发,有列表类型和字典类型等。
    B系统用Java开发,有数组、map等的类型。

    语言不同,基础数据类型格式都不同。
    
    为了方便数据传输,大家约定一个格式:json格式,每种语言都是将自己数据类型转换为json格式,也可以将json格式的数据转换为自己的数据类型。

(2)Python数据类型与json格式的相互转换:

(a)数据类型 -> json ,一般称为:序列化

import json
data = [
    {"id": 1, "name": "武沛齐", "age": 18},
    {"id": 2, "name": "alex", "age": 18},
]
res = json.dumps(data)
print(res) # '[{"id": 1, "name": "\u6b66\u6c9b\u9f50", "age": 18}, {"id": 2, "name": "alex", "age": 18}]'
res = json.dumps(data, ensure_ascii=False)
print(res) # '[{"id": 1, "name": "武沛齐", "age": 18}, {"id": 2, "name": "alex", "age": 18}]'

(b)json格式 -> 数据类型,一般称为:反序列化

import json
data_string = '[{"id": 1, "name": "武沛齐", "age": 18}, {"id": 2, "name": "alex", "age": 18}]'
data_list = json.loads(data_string)
print(data_list)

#[{'id': 1, 'name': '武沛齐', 'age': 18}, {'id': 2, 'name': 'alex', 'age': 18}]

(3)类型要求

        python的数据类型转换为 json 格式,对数据类型是有要求的,默认只支持:

data = [
    {"id": 1, "name": "武沛齐", "age": 18},
    {"id": 2, "name": "alex", "age": 18},
]

其他类型如果想要支持,需要自定义JSONEncoder 才能实现,例如:

import json
from decimal import Decimal
from datetime import datetime
data = [
    {"id": 1, "name": "武沛齐", "age": 18, 'size': Decimal("18.99"), 'ctime': datetime.now()},
    {"id": 2, "name": "alex", "age": 18, 'size': Decimal("9.99"), 'ctime': datetime.now()},
]
class MyJSONEncoder(json.JSONEncoder):
    def default(self, o):
        if type(o) == Decimal:
            return str(o)
        elif type(o) == datetime:
            return o.strftime("%Y-%M-%d")
        return super().default(o)
res = json.dumps(data, cls=MyJSONEncoder,ensure_ascii=False)
print(res)
#[{"id": 1, "name": "武沛齐", "age": 18, "size": "18.99", "ctime": "2024-39-27"}, {"id": 2, "name": "alex", "age": 18, "size": "9.99", "ctime": "2024-39-27"}]

(4)其他功能

json模块中常用的是:

  • json.dumps,序列化生成一个字符串。

  • json.loads,发序列化生成python数据类型。

  • json.dump,将数据序列化并写入文件(不常用)

  • import json
    data = [
        {"id": 1, "name": "武沛齐", "age": 18},
        {"id": 2, "name": "alex", "age": 18},
    ]
    file_object = open('xxx.json', mode='w', encoding='utf-8')
    json_data=json.dump(data, file_object)
    print(json_data)
    file_object.close()
    #None
  • json.load,读取文件中的数据并反序列化为python的数据类型(不常用)

    import json
    file_object = open('xxx.json', mode='r', encoding='utf-8')
    data = json.load(file_object)
    print(data)
    file_object.close()
    #[{'id': 1, 'name': '武沛齐', 'age': 18}, {'id': 2, 'name': 'alex', 'age': 18}]
    

    总结:

            能够深入理解,在项目编码中能够运用本章知识即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2094225.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

定时器方案:时间表盘

目录 一:前言 二:手搓时间表盘 1、任务结点,层级,表盘的结构体 2、表盘的初始化 3、添加定时任务 4、删除定时任务 5、检查任务是否超时 6、清空任务 一:前言 我之前有两篇文章是写定时器方案的,大家…

智菜谱推|基于SprinBoot+vue的智能菜谱推荐系统(源码+数据库+文档)

智能菜谱推荐系统 基于SprinBootvue的智能菜谱推荐系统 一、前言 二、系统设计 三、系统功能设计 系统功能实现 管理员功能模块实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂…

【开源免费】基于SpringBoot+Vue.JS渔具租赁系统(JAVA毕业设计)

本文项目编号 T 005 ,文末自助获取源码 \color{red}{T005,文末自助获取源码} T005,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 渔…

低空经济概念火爆:无人机飞手人才培养先行

随着科技的飞速发展,低空经济作为新兴的经济形态,正以前所未有的速度崛起,成为推动产业升级和经济发展的新引擎。无人机作为低空经济的重要组成部分,其应用领域已从最初的军事侦察、航拍扩展到农业植保、物流配送、环境监测、应急…

使用corrplot绘制行、列不同,且带有p值显著性标注的相关系数图

导读: 相关系数衡量两个变量之间的线性关系,通常以N*N的矩阵形式展示。例如样品vs样品,或者基因vs基因的相关性。本文介绍了使用corrplot R包绘制M*N的相关系数矩阵,例如M个基因表达与N个代谢物信号间的相关性,同时带…

国产芯片+国产操作系统打造办公系统

在《使用国产操作系统作为开发系统》一文中,我介绍了将开发系统从 Ubuntu 替换为 Deepin 系统的过程。经过一个多月的使用,Deepin 系统已然成为我的主力开发平台,其顺手程度让我对国产操作系统的信心大增。于是,我开始将目光瞄向公…

顶级开源许可证详解

目录 软件许可证类型:版权左派和宽容型 顶级开源许可证详解 GNU 通用公共许可证 (GPL) Apache 许可证 Microsoft 公共许可证 (Ms-PL) 伯克利软件发行版 (BSD) 通用开发和分发许可证 (CDDL) Eclipse 公共许可证 (EPL) MIT 许可证 了解你的开源许可证&#…

java编辑器——IntelliJ IDEA

java编辑器有两种选择——IntelliJ IDEA和VsCode。其中IntelliJ IDEA现在是企业用的比较多的,是专门为java设计的,而VsCode则是通过插件来实现Java编辑的。 1.IntelliJ IDEA 官网下载链接:https://www.jetbrains.com/idea/ 注意选择社区版…

AWS-亚马逊网络服务(基础服务)-AWS 定价计算器-概述与动手部署:

让我们来概述并亲身实践如何使用 AWS 定价计算器来计算 概述: AWS 定价计算器是 Amazon Web Services (AWS) 提供的基于 Web 的工具,可帮助用户估算其特定用例的 AWS 服务成本。欢迎来到雲闪世界。 它允许客户建模他们的基础设施并根据他们打算使用的…

【AI 绘画】更快?更省显存?支持 FLUX?使用绘世启动器安装 SD WebUI Forge

使用绘世启动器安装 SD WebUI Forge 下载绘世启动器 绘世启动器下载地址1:https://gitee.com/licyk/term-sd/releases/download/archive/hanamizuki.exe 绘世启动器下载地址2:https://www.bilibili.com/video/BV1ne4y1V7QU 新建一个文件夹取名sd-webui-…

中仕公考怎么样?公务员考试什么时候补录?

公务员考试补录的时间和方法通常因地区和职位的不同有所区别,一般来说,这一过程会在面试、体检和考核环节完成后启动。 如果在招录过程中出现职位空缺或者并未全部招满的情况,就会进行补录。用人单位会通过其官方或公告形式公布相关信息&…

指针5.回调函数与qsort

今天来学习回调函数与qsort 目录 1.回调函数实现模拟计算器代码的简化原代码运行结果简化代码运行结果 qsort函数排序整型数据代码运行结果 qsort排序结构数据代码 qsort函数的模拟实现代码运行结果 总结 1.回调函数 回调函数就是⼀个通过函数指针调用的函数。 如果你把函数的…

JavaEE第22节 TCP段(报文)结构剖析

目录(关于字段有不理解的,哪里不会点哪里😘) 逻辑结构字段解析一、源端口&目的端口二、序号&确认序号三、头部长度四、保留位五、特殊标志位六、窗口大小七、校验和八、紧急指针九、可选选项十、数据 逻辑结构 如图&…

入门Java编程的知识点—>Http协议(day20)

了解http协议是什么掌握http请求信息、响应信息格式 项目目标: 实现本地客户端与服务器一问一答的请求与响应,了解http协议即可. 项目步骤: 服务器端代码编写 先在当前src文件下新建一个包: webserver,再该包下创建一个类Server,书写代码如…

带着耐心细心平常心和编程共舞

编程是什么?一个工具、一门技术还是一个爱好,不同的对待方法会带来不同的心态、产生不同的结果。编程需要扎实的基础、严密的思维和开阔的视角,新技术和框架日新月异,只有抱着科学、乐在其中的态度才能掌握高效的学习、实践方法。…

Matrix:重塑APM领域,以简驭繁的性能监控新纪元

在数字化转型的浪潮中,应用程序的性能监控(APM)已成为企业IT架构中不可或缺的一环。随着业务复杂度的提升和用户对体验要求的日益增高,如何高效、精准地监控并优化应用性能,成为了每个开发者和技术团队面临的重大挑战。…

机器学习(五) -- 监督学习(8) --神经网络1

系列文章目录及链接 上篇:机器学习(五) -- 无监督学习(2) --降维2 下篇: 前言 tips:标题前有“***”的内容为补充内容,是给好奇心重的宝宝看的,可自行跳过。文章内容被…

2.3导数与微分的基础与应用

1. 导数的基本概念 大家好,欢迎来到我们的数学大讲堂!今天我们要聊聊一个有点酷又有点恐怖的东西——导数。别担心,不是让你在黑板上画曲线的那种,而是关于“变化率”的一种数学表达。 那么,什么是导数呢&#xff1f…

利用实用规模量子计算模拟宇宙中最极端的环境

华盛顿大学和劳伦斯伯克利国家实验室最近的研究展示了可扩展的技术,有朝一日可以实现最高能量下的基础物理实验模拟。 目录 核物理和高能物理的实用规模模拟 我们的模拟方法 Qiskit 如何使我们的实验成为可能 展望量子模拟技术的未来 粒子物理学的标准模型囊括了我们…

005.Python爬虫系列_浏览器开发者工具(详解)

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈 PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈 Oracle数…