Python解释器:CPython 解释器

一、什么是python解释器

Python解释器是一种用于执行Python代码的程序。

它将Python源代码转换为机器语言或字节码,从而使计算机能够执行。

1.1 Python解释器分类

1、CPython

CPython 是 Python 的主要实现,由 C 语言编写。大多数用户在日常开发中使用的 Python 版本都是 CPython。

2、Jython

Jython:将 Python 代码编译成 Java 字节码,可以在 JVM 上运行。这使得 Python 代码可以与 Java 互操作,特别适合于需要与 Java 生态系统集成的项目。

3、IronPython

IronPython:在 .NET 平台上运行的 Python 实现,将 Python 代码编译成 .NET 的中间语言(IL),可以与 .NET 框架集成

4、PyPy

PyPy:一个通过 JIT(即时编译)技术提高性能的 Python 解释器。与 CPython 相比,PyPy 在某些情况下可以显著提升代码的执行速度。

每种解释器都有其独特的优势和适用场景,选择合适的解释器取决于项目的需求,例如性能要求、平台兼容性、与其他语言的集成等。

总体来说,Python 解释器是 Python 语言的关键组成部分,它负责将开发者编写的高级 Python 代码转换为底层系统能够理解和执行的指令集,从而实现代码的运行和功能实现。

1.2 Python 与Java运行方式不同

Python 和 Java 在运行方式上有显著的区别,这些区别主要源于它们的执行环境和语言设计的差异:

1、解释执行 vs 编译执行

  • Python 是一种解释型语言,它的代码在运行时通过解释器逐行地执行。Python 代码会被解释器即时翻译成字节码,然后由Python虚拟机(CPython、PyPy等)执行。这种解释方式使得 Python 代码可以跨平台运行,但通常比编译型语言执行速度较慢。

  • Java 是一种编译型和解释型混合的语言。Java 代码首先被编译成字节码(.class 文件),然后由Java虚拟机(JVM)解释执行。JVM 可以将字节码实时编译成本地机器码(即时编译),从而提高执行效率。这种方式结合了编译型语言的高效性和解释型语言的跨平台特性。

2、运行时环境

  • Python 的运行时环境由解释器管理,不需要显式的编译步骤。开发者可以直接运行 .py 文件,由解释器执行其中的代码。

  • Java 的运行时环境需要先将源代码编译成字节码,然后在JVM上运行。这个过程中包含了编译、装载、链接和初始化等步骤。JVM 负责在不同平台上执行字节码,实现了“一次编写,到处运行”的跨平台特性。

3、性能

  • 由于 Python 是解释执行的,其执行速度通常比较慢,特别是对于大量计算密集型的任务。尽管有些优化措施(如使用JIT编译的PyPy)可以改善性能,但通常不及编译型语言。

  • Java 的执行速度较快,因为字节码可以被JVM即时编译成本地机器码。这使得 Java 适合于需要高性能的应用程序,如企业级应用、大型系统等。

4、静态类型 vs 动态类型

  • Python 是一种动态类型语言,变量的类型在运行时确定,可以动态改变。

  • Java 是一种静态类型语言,所有的变量和表达式在编译时期就确定其类型,并且类型通常是严格检查的。

总结来说,Python 和 Java 在运行方式上的不同主要体现在解释执行 vs 编译执行、运行时环境、性能特征和类型系统等方面。这些特性决定了它们在不同场景下的适用性和优劣势。

二、CPython解释器

CPython 是 Python 的官方解释器。

在日常语境中,人们有时会交替使用“Python版本”和“Python解释器版本”,但从技术角度来看,它们指的是同一个事物:由Python官方发布的、具有特定版本号的软件实现。

当你从Python官网下载并安装了Python 3.8和Python 3.9,你的系统中确实会有两个不同版本的Python解释器。每个版本都有其独立的安装目录、可执行文件(例如python.exe)、标准库和可能的第三方库。

当你说“我有Python 3.8和Python 3.9两个版本的解释器”时,实际上你是在说你的系统中安装了两个不同版本的Python。

查看python解释器的位置(就是我们常说的python安装的位置

which python

win的用户解释器为pyhton.exe

2.1 CPython解释器结构

CPython 是 Python 的官方解释器,它用 C 语言实现,是 Python 最常用的解释器之一。下面是 CPython 解释器的基本结构和一些关键组成部分的详细介绍:

当谈论CPython解释器的基本结构时,我们需要关注几个关键组成部分:

1、词法分析器(Lexer)和语法分析器(Parser)

  • 词法分析器负责将源代码转换成标记(tokens),这些标记是语法分析器的输入。它识别出代码中的关键字、标识符、运算符等基本单元。
  • 语法分析器将这些标记转换为抽象语法树(Abstract Syntax Tree,AST)。AST 是源代码的抽象表示形式,捕捉了代码结构和语义。

2、编译器

  • CPython 在解释执行之前会对 AST 进行编译,生成字节码(bytecode)。字节码是一种与平台无关的中间代码,类似于Java的字节码。它包含一系列的指令(如 LOAD_CONST, CALL_FUNCTION),用于在虚拟机中执行相应的操作。

3、解释器核心 (Interpreter Core):

  • 字节码解释器 (Bytecode Interpreter):CPython 的核心功能是执行 Python 源代码转换而来的字节码。字节码是一种中间形式,可以被 CPython 解释器执行。
  • 内存管理 (Memory Management):CPython 使用自己的内存管理器来管理 Python 对象的分配和释放。这包括引用计数和垃圾回收机制。
  • 解释器主循环 (Interpreter Main Loop):解释器的主循环负责从字节码中读取指令,并执行这些指令以完成对 Python 代码的解释和执行。

4、语言核心 (Language Core):

  • 数据类型 (Data Types):CPython 实现了 Python 的基本数据类型,如整数、浮点数、列表、元组、字典等。这些类型在 CPython 中都有对应的 C 结构体表示。
  • 对象模型 (Object Model):CPython 使用 C 结构体来表示 Python 中的对象,例如 PyIntObject 表示整数对象,PyListObject 表示列表对象等。
  • 异常处理 (Exception Handling):CPython 通过 C 的异常处理机制来实现 Python 中的异常处理功能。

5、标准库 (Standard Library):

  • CPython 包含了丰富的标准库,提供了大量的功能和工具,用于处理文件 I/O、网络通信、多线程编程、正则表达式等。

6、扩展机制 (Extension Mechanism):

  • CPython 允许开发者使用 C 或 C++ 编写扩展模块,这些扩展模块可以与 Python 的核心部分无缝集成,扩展 Python 的功能。这些扩展模块可以通过 Python 的 C API 与解释器进行交互。

7、工具和实用程序 (Tools and Utilities):

  • CPython 还包括了一些工具和实用程序,如解释器启动器 (python)、交互式解释器 (python -i)、源码调试器 (pdb) 等等,这些工具使得开发和调试 Python 程序更加便捷。

这些组件共同工作,构成了CPython 解释器的基本结构,支持了 Python 语言的解释、执行和扩展。

2.2 CPython 解释器执行 Python 代码的基本过程

CPython 解释器执行 Python 代码的基本过程:

源代码 -> 词法分析 -> 语法分析 -> 字节码生成 -> 字节码执行

1、读取 Python 源代码:

CPython 会首先读取整个 Python 源代码文件。


2、词法分析(Lexical Analysis):

词法分析器将源代码分解为词法单元(tokens),例如标识符、运算符、关键字等。这些 tokens 是语法分析器的输入。


3、语法分析(Syntax Analysis):

语法分析器根据词法单元构建语法树(Abstract Syntax Tree,AST)。它检查语法的正确性,确保代码符合 Python 的语法规则。

4、生成字节码(Bytecode Generation):

一旦语法分析器生成了 AST,CPython 将 AST 转换为字节码。字节码是一种中间表示形式,类似于汇编语言,但是针对 Python 虚拟机(PVM)执行的指令集。


5、执行字节码(Bytecode Execution):

最后,Python 虚拟机(PVM)执行生成的字节码。PVM 是 CPython 中的核心组成部分,负责解释和执行字节码指令,操作 Python 对象,管理内存,处理异常等。
 

三、CPython 的内存管理机制

CPython 的内存管理机制主要包括两个关键部分:内存分配和垃圾回收。

CPython 是 Python 的一种实现,它使用了 C 语言来编写核心的解释器部分。Python 的内存管理在 CPython 中是通过 Python 对象的引用计数和垃圾回收机制来实现的。

3.1. 内存分配

在 CPython 中,内存分配主要是针对 Python 对象的管理。Python 中的所有对象(如整数、浮点数、字符串、列表等)都存储在堆上,而不是栈上。具体的内存分配机制如下:

  • 内存池(Memory Pool):CPython 使用了内存池技术来管理小型对象的内存分配。内存池主要包括针对常用的小对象大小(如 1-512 字节)的预先分配和缓存。这样做可以减少内存碎片化和提高内存分配效率。

  • 引用计数(Reference Counting):CPython 使用引用计数来追踪和管理内存中对象的引用情况。每个对象都有一个引用计数器,记录当前指向该对象的引用数。当引用计数减少到 0 时,表示没有任何引用指向该对象,CPython 将释放该对象占用的内存空间。

3.2 垃圾回收(Garbage Collection)

虽然引用计数可以有效地处理大部分对象的内存释放,但是对于循环引用(两个或多个对象相互引用,但是没有被外部对象引用)情况,引用计数机制无法正确处理。为了解决这个问题,CPython 引入了垃圾回收机制,主要通过以下方式来回收循环引用的对象:

  • 标记-清除算法(Mark and Sweep):CPython 的主要垃圾回收机制是基于标记-清除算法。在周期性的垃圾回收过程中,Python 解释器会遍历所有的对象,标记出活动对象(还在使用的对象),然后清除未标记的对象(即被释放的对象)。这个过程确保了循环引用的对象可以正确地被释放和回收。

  • 分代回收(Generational Collection):CPython 使用了分代回收的策略,将对象分为不同的代(generations)。一般情况下,新创建的对象存放在年轻代(young generation),而经过多次垃圾回收仍然存活的对象会被移到老年代(old generation)。这种分代回收机制可以提高垃圾回收的效率,因为大部分对象都是短时间内就不再使用的。

3.2.1  垃圾回收(Garbage Collection)

CPython 使用分代垃圾回收机制,主要包括三个代:

  • 第0代(Generation 0):包含新创建的对象。
  • 第1代(Generation 1):包含经过一次垃圾回收仍存活的对象。
  • 第2代(Generation 2):包含经过多次垃圾回收仍存活的对象。

垃圾回收通过周期性地检查和清理不再被引用的对象来回收内存。CPython 使用了标记-清除(mark and sweep)算法来进行垃圾回收:

  • 标记阶段:从一组根对象(如当前活跃的 Python 对象、全局变量等)出发,遍历对象的引用关系,标记所有可以访问到的对象。
  • 清除阶段:清除所有未被标记的对象,释放它们占用的内存空间。

1. 引用计数(Reference Counting)

在 CPython 中,每个 Python 对象都包含一个引用计数器,用来记录当前指向该对象的引用数目。当一个对象被创建时,引用计数初始化为 1。当对象被引用时,引用计数增加;当对象不再被引用时,引用计数减少。当引用计数降为 0 时,表示没有任何指针指向该对象,此时对象被认为是不可达的,可以被销毁和回收。

引用计数的优点是实时性高,对象在不再需要时可以立即释放。但是,引用计数无法处理循环引用的情况,例如对象 A 引用了对象 B,而对象 B 同时也引用了对象 A,这会导致循环引用的对象永远无法被释放,从而造成内存泄漏。为了解决循环引用问题,CPython 引入了垃圾回收机制。

2. 对象的生命周期

在 Python 中,对象的生命周期由引用计数和垃圾回收共同管理:

  • 引用计数 管理对象的短期生命周期,即对象在不再被引用时立即释放。
  • 垃圾回收 管理长期存活的对象,解决循环引用等问题,确保内存的有效利用。

总结

CPython 的内存管理机制通过内存池技术、引用计数和垃圾回收算法,有效地管理和释放 Python 对象的内存。这些机制不仅确保了内存的高效使用,也保证了 Python 程序的稳定性和性能。

四、Cpython中的堆(heap)和栈(stack)

在 CPython 中,堆和栈是两个不同的概念,它们并不直接对应于 Python 语言中的堆(heap)和栈(stack)数据结构,而是指内存管理的两个不同区域,用于存储程序执行中的不同类型的数据:

1、堆(Heap)

在 CPython 中,堆指的是用于存储所有对象和数据的动态分配内存区域。这些对象包括所有的 Python 对象、字符串、列表等。Python 中的堆是由 Python 的内存管理器(Memory Allocator)进行管理的,它会动态分配和释放内存空间以满足程序运行时的需求。

2、栈(Stack)

栈在 CPython 中指的是执行函数调用时使用的栈空间。每当调用一个函数时,Python 解释器会为该函数创建一个帧对象(frame),帧对象包含了函数的调用信息、局部变量、返回地址等。这些帧对象会形成一个调用栈,即调用栈帧(call stack frames),用于管理函数的嵌套调用和返回过程。

具体来说:

  • 堆(Heap):存储所有的对象和数据,由 Python 内存管理器进行动态分配和释放。
  • 栈(Stack):存储函数调用时的执行上下文信息,如局部变量、函数参数等。

这两个概念不同于数据结构中的堆和栈,而是涉及到 CPython 内存管理和执行流程中的两个重要部分。

五、为什么Python 的模块本身就是天然的单例模式

5.1、实现单例模式的方式:使用模块

Python 的模块本身就是天然的单例模式。模块在第一次导入时会被初始化,并且只会初始化一次。其他模块导入同一个模块,实际上是导入了同一个实例。

# singleton_module.py
class Singleton:def __init__(self):passsingleton_instance = Singleton()

其他模块导入 singleton_module 即可使用单例实例 singleton_instance

5.2、为什么Python 的模块本身就是天然的单例模式

在 Python 中,模块(module)在第一次被导入时会被初始化,并且在整个解释器进程的生命周期中只会被初始化一次。这个特性使得模块在 Python 中天然具备了单例模式的效果。

让我们深入探讨一下为什么这种特性能够实现单例模式:

1、初始化一次:

  • 当 Python 解释器第一次遇到 import module_name 语句时,它会执行模块 module_name.py 中的代码,并将其中定义的函数、类、变量等加载到内存中。这个过程称为模块的初始化。
  • 初始化完成后,模块会被缓存起来,以便后续的导入操作不会重复执行初始化过程。

2、模块缓存:

  • Python 使用 sys.modules 字典来缓存所有已经导入的模块。在导入一个模块时,Python 首先检查这个字典中是否已经存在这个模块的记录。
  • 如果存在,则直接从 sys.modules 中获取已经加载过的模块对象,而不会再重新执行模块的初始化代码。

3、单例效果

  • 因为模块在解释器生命周期内只会被初始化一次,并且初始化后的实例被缓存,后续的导入操作都会直接使用这个缓存的实例。这意味着无论在代码的哪个地方导入这个模块,得到的都是同一个模块实例。
  • 这与单例模式的核心思想相符:保证一个类只有一个实例,并提供一个全局访问点。

4、适用性

  • Python 中的模块天然地具备了单例模式的特性,这种方式简单而有效,适合大多数情况下需要使用单例的场景。
  • 开发者可以利用模块来管理全局状态或共享资源,而不必手动实现单例模式的复杂性,如线程安全的实现等。

总结来说,Python 中的模块在首次导入时被初始化且只初始化一次,并且后续的导入操作都是获取同一个实例,这种特性使得模块天然具备了单例模式的效果,从而简化了单例模式的实现过程。

5.3 代码示例

一个常见的应用场景是在一个 Web 应用程序中使用单例模式来管理全局的配置信息或者数据库连接池。让我们以管理数据库连接池为例进行说明。

假设我们有一个数据库连接池的模块 database.py,我们希望在整个应用程序中共享同一个数据库连接池,以提高效率和资源利用率。

database.py:

import psycopg2
from psycopg2 import pool
from configparser import ConfigParser# 读取数据库配置
config = ConfigParser()
config.read('database.ini')# 获取数据库连接池配置
db_params = {'minconn': config.getint('Database', 'minconn'),'maxconn': config.getint('Database', 'maxconn'),'dbname': config.get('Database', 'dbname'),'user': config.get('Database', 'user'),'password': config.get('Database', 'password'),'host': config.get('Database', 'host'),'port': config.get('Database', 'port')
}# 创建 PostgreSQL 连接池
connection_pool = pool.ThreadedConnectionPool(**db_params)def get_connection():"""获取数据库连接"""return connection_pool.getconn()def release_connection(conn):"""释放数据库连接"""connection_pool.putconn(conn)

在这个示例中,database.py 模块通过 psycopg2 提供的 ThreadedConnectionPool 创建了一个 PostgreSQL 数据库连接池。get_connection() 函数用于获取一个数据库连接,而 release_connection() 函数用于释放数据库连接回连接池。

使用示例:

# main.pyfrom database import get_connection, release_connectiondef query_data():conn = get_connection()cursor = conn.cursor()cursor.execute("SELECT * FROM users")rows = cursor.fetchall()cursor.close()release_connection(conn)return rowsif __name__ == "__main__":data = query_data()print(data)

main.py 中,我们通过导入 database.py 并调用 get_connection()release_connection() 函数来获取和释放数据库连接。这样,整个应用程序中的所有模块都共享同一个数据库连接池,确保了资源的有效利用和数据库连接的高效管理。

在不同的文件中多次调用 get_connection(),但它们都会获取同一个数据库连接池中的连接。这是因为 database.py 模块中的 connection_pool 是在模块加载时创建的,并且在整个应用程序的生命周期中都保持不变。

Python 的模块在程序中只会加载一次,因此 database.py 模块中的 connection_pool 对象也只会在第一次导入时创建一次。之后的每次导入和调用 get_connection() 都会使用同一个连接池实例,确保了在整个应用程序中共享同一个数据库连接池。

在 Python 中,对象通常存储在堆(heap)中,包括连接池对象 connection_pool 以及它所管理的连接对象。具体来说:

  1. 连接池对象 (connection_pool):在 Python 中,所有的对象,包括类实例和连接池对象,都存储在堆中。堆是一块用于动态分配内存的区域,用于存储程序运行时创建的对象和数据结构。连接池对象 connection_pool 也会被分配到堆上。

  2. 连接对象:连接池管理的实际数据库连接对象也会存储在堆中。这些连接对象是由数据库连接池动态创建和管理的,每个连接对象实际上是一个 Python 对象,也存储在堆中。

连接池对象本身在 Python 中是一个自定义的数据结构,通常是通过 Python 内置的数据结构(如字典或列表)实现的。这些数据结构也会被分配到堆上。

总之,无论是连接池对象还是其管理的连接对象,它们都存储在 Python 的堆中。

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

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

相关文章

“机器说人话”-AI 时代的物联网

万物互联的物联网愿景已经提了许多年了,但是实际效果并不理想,除了某些厂商自己的产品生态中的产品实现了互联之外,就连手机控制空调,电视机和调光灯都没有实现。感觉小米做的好一点,而华为的鸿蒙的全场景,…

MMCV 核心组件分析(一):整体概述

概述 MMCV 是计算机视觉研究的基础库,并提供以下功能。

Go基础编程 - 12 -流程控制

流程控制 1. 条件语句1.1. if...else 语句1.2. switch 语句1.3. select 语句1.3.1. select 语句的通信表达式1.3.2. select 的基特性1.3.3. select 的实现原理1.3.4. 经典用法1.3.4.1 超时控制1.3.4.2 多任务并发控制1.3.4.3 监听多通道消息1.3.4.4 default 实现非堵塞读写 2. …

海康威视综合安防管理平台 detection 前台RCE漏洞复现

0x01 产品简介 海康威视综合安防管理平台是一套“集成化”、“智能化”的平台,通过接入视频监控、一卡通、停车场、报警检测等系统的设备。海康威视集成化综合管理软件平台,可以对接入的视频监控点集中管理,实现统一部署、统一配置、统一管理和统一调度。 0x02 漏洞概述 海康…

k8s中部署nacos

1 部署nfs # 在k8s的主节点上执行 mkdir -p /appdata/download cd /appdata/download git clone https://github.com/nacos-group/nacos-k8s.git 将nacos部署到middleware的命名空间中 kubectl create namespace middleware cd /appdata/download/nacos-k8s # 创建角色 kub…

JavaScript中==和===的区别

🧑‍💻 写在开头 点赞 收藏 学会🤣🤣🤣 前言 JavaScript 中的相等运算符无疑是新手开发者最容易混淆的知识点之一。 和这两个运算符的细微差别往往会在代码中造成一些令人困惑的行为 在本文中,我们将深入探讨这两个…

Google Chrome 浏览器在链接上点右键的快捷键

如今,越来越多的软件都懒得设个快捷键,就算设置了连个下划线也懒得加了。 谷歌浏览器右键 > 链接另存为... 和 复制链接地址 的快捷键 (如图)

Flink架构底层原理详解:案例解析(43天)

系列文章目录 一、Flink架构(掌握) 二、Flink代码案例(掌握) 三、UDF(熟悉) 四、Flink常见面试题整理 文章目录 系列文章目录前言一、Flink架构(掌握)1、系统架构1.1 通信&#xff…

SystemUI默认去掉底部导航栏

一、背景 在Android系统中,SystemUI负责管理系统的状态栏、导航栏等用户界面元素。若要在SystemUI中默认去掉底部导航栏, 可以通过以下几种方法实现: 1. 修改布局文件 在Android的SystemUI源代码中,底部导航栏的布局文件通常…

SpringBoot+Session+redis实现分布式登录

SpringBootSessionRedis实现分布式登录功能实现 文章目录 目录 文章目录 前言 一、引库 二、修改配置文件 三、使用 四、解决乱码问题 1.引库 2.配置redis序列化 3.配置Session-Redis序列化 前言 这里简单介绍一下,如果你想多台机器部署你的项目的话,在…

重大突破!OpenAI 推出 GPT-4o mini,AI 领域再掀波澜!

北京时间 7 月 18 日晚,OpenAI 重磅推出“小模型”GPT-4o mini,其在文本智能和多模态推理方面展现出卓越性能,超越 GPT-3.5 Turbo,在 LMSYS“聊天机器人对战”排行榜上也力压 GPT-4。 GPT-4o mini 支持 128K Token 的长上下文窗口…

一起学Java(1)-新建一个Gradle管理的Java项目

一时兴起,也为了便于跟大家同步学习进展和分享样例代码,遂决定创建一个全新的Java项目,并通过Github与大家分享。本文就是记录该项目的创建过程以及其中的一些知识要点(如Gradle等)。为了紧跟技术潮流和提高操作效率&a…

污染物CMAQ模型的安装

CMAQ安装教程(基于intel编译器) 简介 CMAQ(Community Multiscale Air Quality)系统是由美国国家环境保护局(EPA, Environmental Protection Agency)于1998年发布,是用于估算臭氧、颗粒物、有毒化合物和酸沉降等大气污…

第5讲:Sysmac Studio中的硬件拓扑

Sysmac Studio软件概述 一、创建项目 在打开的软件中选择新建工程 然后在工程属性中输入工程名称,作者,类型选择“标准工程”即可。 在选择设备处,类型选择“控制器”。 在版本处,可以在NJ控制器的硬件右侧标签处找到这样一个版本号。 我们今天用到的是1.40,所以在软…

DocRED数据集

DocRED数据集文件夹包含多个JSON文件,每个文件都有不同的用途。以下是这些文件的用途解释以及哪个文件是训练集: 文件解释 dev.json:包含开发集(验证集)的数据,通常用于模型调优和选择超参数。 label_map…

工业4.0与智能制造解决方案(149页PPT下载)

工业4.0,也被称为第四次工业革命,是一场将先进信息技术与制造业深度融合的全球性变革。这一概念起源于2011年德国提出的高科技战略项目,旨在通过利用物联网(IoT)、大数据、云计算、人工智能(AI)…

海康威视工业相机SDK+Python+PyQt开发数据采集系统(支持软件触发、编码器触发)

海康威视工业相机SDKPythonPyQt开发数据采集系统(支持软件触发、编码器触发) pythonpyqt开发海康相机数据采集系统 1 开发软件功能: 支持搜索相机:Gige相机设备和USB相机设备支持两种触发模式:软件触发和编码器触发支…

Python基础知识——(005)

文章目录 P21——20. 比较运算符 P22——21. 逻辑运算符 P23——22. 位运算和运算符的优先级 P24——23. 本章总结和章节习题 P21——20. 比较运算符 示例3-17—比较运算符的使用: P22——21. 逻辑运算符 示例3-18—逻辑运算符的使用: print(True and T…

群管机器人官网源码

一款非常好看的群管机器人html官网源码 搭建教程: 域名解析绑定 源码文件上传解压 访问域名即可 演示图片: 群管机器人官网源码下载:客户端下载 - 红客网络编程与渗透技术 原文链接: 群管机器人官网源码

Python设计模式:巧用元类创建单例模式!

✨ 内容: 今天我们来探讨一个高级且实用的Python概念——元类(Metaclasses)。元类是创建类的类,它们可以用来控制类的行为。通过本次练习,我们将学习如何使用元类来实现单例模式,确保某个类在整个程序中只…