Python测试框架:pytest与assert断言
Python提供了多种测试工具,其中pytest是最流行的单元测试框架之一。本文将介绍Python中的assert语句以及pytest框架的基本用法。 一、assert语句1. 基本用法1234567# assert 条件x = 10assert x > 0 # 条件为True,无输出# assert 条件, 错误信息x = -5assert x > 0, "x必须大于0" # 抛出AssertionError 2. 常见用途12345678910def divide(a, b): assert b != 0, "除数不能为零" return a / bdef validate_age(age): assert 0 <= age <= 150, "年龄必须在0到150之间" return ageprint(validate_age(25)) # 正常# validate_age(-5) # 抛出AssertionError 二、pytest框架1. 基本安装和使...
C++ 函数定义与调用中的符号体系
引言在 C++ 函数的定义与调用过程中,< >、( )、[ ]和{ }等符号具有明确的语义边界和使用规范。理解这些符号的准确含义和应用场景,对于编写正确、高效的 C++ 代码至关重要。 一、< >在函数模板中的应用尖括号< >主要用于函数模板的参数列表,用于指定模板类型参数或非类型参数。 1.1 函数模板定义中的< >在函数模板定义中,< >用于声明模板参数列表: 1234template <typename T> // 模板参数列表T max(T a, T b) { return (a > b) ? a : b;} 这里的声明了一个类型参数T,使函数能够接受任意类型的参数。 1.2 函数模板调用中的< >在调用函数模板时,可以显式指定模板参数: 12int result1 = max<int>(3, 5); // 显式指定模板参数为intdouble result2 = max<double>(3.2, 5.7); // 显...
Python引用机制:无指针设计与内存管理
Python是一种高级编程语言,其设计理念之一就是让开发者无需关心底层的内存管理。因此,Python中没有像C或C++那样的指针概念。本文将介绍Python的引用机制以及它与指针的区别。 一、Python的引用机制1. 变量即引用在Python中,变量更像是标签或引用,而不是存储数据的容器: 1234567891011# 创建变量x = 10y = xprint(x) # 10print(y) # 10# x和y指向同一个对象y = 20print(x) # 10(x不受影响)print(y) # 20 2. 对象与引用Python中的每个对象都有: 身份(id):对象的唯一标识 类型(type):对象的类型 值(value):对象的值 123456x = [1, 2, 3]y = xprint(id(x)) # 对象身份print(id(y)) # 相同身份print(x is y) # True:x和y指向同一对象 二、可变对象与不可变对象1. 不可变对象不可变对象包括:整数、浮点数、字符串、元组等 1234567# 不可变对象x = 10y = xy ...
Python IO操作:文件读写与标准输入输出
Python的IO(输入/输出)操作是编程中非常基础且重要的部分,它允许程序与外部世界进行交互。本文将详细介绍Python中的文件读写操作、标准输入输出以及相关的最佳实践。 一、文件读写操作1. 打开和关闭文件在Python中,使用open()函数打开文件,使用close()方法关闭文件。 123456789# 打开文件file = open('example.txt', 'r')# 操作文件content = file.read()print(content)# 关闭文件file.close() 2. 文件打开模式 模式 描述 r 只读模式(默认) w 写入模式,会覆盖现有文件 a 追加模式,在文件末尾添加内容 x 独占创建模式,如果文件已存在则报错 b 二进制模式 t 文本模式(默认) + 读写模式 12345678# 二进制模式打开with open('image.jpg', 'rb') as f: data = f.read()# 读写模...
C++虚基类与虚函数的内存布局
一、40字节对象大小的组成结构在标准C++中,一个包含虚基类和虚函数的类实例会由以下组件构成: 内存结构分解1234[对象地址] ├── 虚函数表指针 (8字节) → 用于多态调用├── 偏移量表 (16字节) → 处理虚基类偏移└── 数据成员 (16字节) → 本类的实际数据 关键点: 虚函数表指针会占用8字节(64位系统)或4字节(32位系统) 虚基类引入的偏移量表通常需要16字节(包含两个虚基类指针) 本类数据成员占用16字节(假设包含两个double类型成员) 总内存大小 = 虚函数表指针 + 偏移量表 + 数据成员 二、虚基类继承关系考虑以下类继承结构: 1234567class Figure { virtual void draw() = 0; }; // 虚基类class Space { virtual void calc() = 0; }; // 虚基类class Circle : virtual public Figure, virtual public Space { double ...
Python数据结构:列表与字典操作
Python中的列表(List)和字典(Dictionary)是两种最常用的数据结构。列表类似于数组,字典是一种键值对数据结构。本文将详细介绍这两种数据结构的用法。 一、列表(List)1. 基本操作123456789101112# 创建列表fruits = ["apple", "banana", "cherry"]numbers = [1, 2, 3, 4, 5]mixed = [1, "hello", 3.14, True]# 访问元素print(fruits[0]) # appleprint(fruits[-1]) # cherry# 修改元素fruits[0] = "orange"print(fruits) # ['orange', 'banana', 'cherry'] 2. 列表方法12345678910111213141516# 添加元素fruits = ["apple", &q...
C++ 纯虚函数与抽象类
一、什么是面向对象中的抽象在面向对象编程中,抽象是一种将复杂事物简化的方法,它关注对象的本质特征而非具体实现细节。想象一下,当我们谈论 "交通工具" 时,我们不会具体指明是汽车、自行车还是飞机,而是关注它们共同的特性:能够运输人和物,可以移动到不同地点等。 以游戏开发为例,不同角色(战士、法师、刺客)都具备移动、攻击、获取经验等行为,将这些共性抽象出来,就能构建出一个通用的角色概念。这种抽象思维在软件设计中非常有价值,它能帮助我们: 建立清晰的系统架构,将问题分解为合理的模块 定义通用接口,使不同实现可以互换使用 提高代码复用性,减少重复开发 便于团队协作,不同开发者可以基于相同接口并行工作 二、纯虚函数:定义接口的特殊函数纯虚函数是一种特殊的虚函数,它只有声明而没有具体实现,专门用于定义接口规范。在语法上,它的声明需要在函数原型后加上 "=0"。例如: 1234class AbstractClass {public: virtual double getArea() = 0; // 纯虚函数,计算图形...
Python循环结构:while与for迭代器详解
Python提供了两种主要的循环结构:while循环和for循环。本文将详细介绍这两种循环的使用方法,以及range()迭代器的使用。 一、while循环1. 基本语法12345count = 0while count < 5: print(count) count += 1# 输出:0, 1, 2, 3, 4 2. while-else结构123456count = 0while count < 5: print(count) count += 1else: print("循环正常结束") # 循环正常结束时执行 3. 无限循环12345while True: user_input = input("输入 'quit' 退出: ") if user_input == "quit": break print(f"你输入了: {user_input}") 二、for循环1. 基本语法...
C++ 虚析构函数详解:从原理到实践
一、内存管理与析构函数的基础核心原理 在C++中,对象的内存分配与释放是通过构造函数和析构函数完成的。当创建一个对象时: 构造函数负责初始化资源(如内存申请、文件打开) 析构函数负责释放资源(如内存回收、文件关闭) 资源管理规律 无资源类:普通类对象的析构无需特殊处理,编译器自动调用 有资源类:需要显式定义析构函数来处理资源释放 继承体系:当基类可能被继承时,必须考虑析构顺序问题 在单继承场景下,析构函数的调用遵循 "先派生类、后基类" 的顺序,这确保了资源释放的安全性。然而,当引入多态(使用基类指针指向派生类对象)时,普通析构函数就会暴露出严重的缺陷。 问题的引出考虑以下场景: 我们有一个基类Base和派生类Derived 使用Base*类型的指针指向Derived类的对象 当通过基类指针删除对象时,会发生什么? 典型场景 123456789class Base {public: ~Base() { cout << "Base析构" << endl; }...
Python匹配语句:match-case与switch对比
Python 3.10引入了match语句,这是一种强大的模式匹配机制,类似于其他语言中的switch语句,但功能更加强大。本文将详细介绍Python中match语句的用法。 一、match语句的基本用法1. 基本语法1234567891011121314def http_status(status): match status: case 200: return "OK" case 404: return "Not Found" case 500: return "Internal Server Error" case _: return "Unknown"print(http_status(200)) # 输出:OKprint(http_status(404)) # 输出:Not Foundprint(http_status(999)) ...
C++ 虚函数访问控制
一、虚函数的访问控制虚函数的访问控制(public、protected、private)会影响其在派生类中的重写和调用规则,这是容易混淆的知识点。 1. public 虚函数基类中 public 的虚函数在派生类中可以被重写为 public 或 protected,但不能重写为 private(在 C++11 前允许,C++11 后被禁止): 123456789101112131415161718192021222324252627282930313233343536373839class Base {public: virtual void publicFunc() { cout << "Base::publicFunc" << endl; }};class Derived : public Base {public: // 正确:重写为public void publicFunc() override { cout << "Deri...
Python异常处理:try-except-finally-else机制
Python的异常处理机制是一种强大的错误处理方式,使用try、except、finally和else关键字来捕获和处理程序运行过程中的错误。本文将详细介绍Python异常处理的各种用法。 一、基本语法1. try-except结构123456try: # 可能引发异常的代码 result = 10 / 0except ZeroDivisionError: # 处理特定异常 print("不能除以零") 2. 捕获异常信息12345try: result = 10 / 0except ZeroDivisionError as e: print(f"错误类型: {type(e).__name__}") print(f"错误信息: {e}") 3. 多个except子句1234567try: value = int("abc") result = 10 / 0except ValueError: pri...
C++ 虚函数与多态实现机制
一、虚函数核心概念框架1.1 虚函数定义虚函数是通过virtual关键字声明的成员函数,允许派生类重写基类的行为。其本质是为实现运行时多态服务,通过动态绑定机制,在程序运行时决定调用哪个类的函数实现。 类比理解:想象一个图书馆管理系统,每个书架都有一个统一的借书接口。当借书时,系统根据实际书架类型( Hardcover/Book/Reference)选择对应的借书规则。 1.2 多态实现四要素 基类指针/引用 虚函数声明 派生类重写 动态绑定调用 关键概念:虚函数定义、多态特性、静态与动态绑定差异 示例: 12345678910111213141516171819202122232425262728293031323334353637#include <iostream>using namespace std;class Animal {public: virtual void speak() { cout << "Animal speak" << en...
Python条件表达式:链式比较与短路求值
Python支持一种独特的语法特性:条件表达式可以连写。这种链式比较(Chained Comparisons)可以让代码更加简洁和易读。本文将详细介绍Python中条件表达式连写的用法。 一、链式比较的基本用法1. 数学风格比较123456789# 传统写法x = 5if x > 0 and x < 10: print("x在0到10之间")# Python连写写法x = 5if 0 < x < 10: print("x在0到10之间") 2. 更多示例1234567891011121314# 判断是否在某个范围内age = 25if 18 <= age <= 65: print("工作年龄") # 输出:工作年龄# 链式不等式x = 0.5if 0 < x < 1: print("x是0到1之间的分数") # 输出:x是0到1之间的分数# 多个比较a, b, c = 3, 5, 7if a < b < c: ...
C++多态机制解析:重载、重写与隐藏
一、概念C++ 的多态机制主要通过三个核心概念实现,它们在编译和运行时有着截然不同的处理方式: 概念 定义 绑定时机 核心特征 函数重载 同一作用域内,函数名相同但参数列表不同的函数 编译时 静态多态,基于参数列表区分 函数重写 派生类中重新定义基类中的虚函数,函数签名完全相同 运行时 动态多态,基于对象实际类型调用 函数隐藏 派生类中定义的函数遮蔽基类中同名函数,无论参数是否相同 编译时 名称遮蔽,基类函数被隐藏 注:函数签名包括函数名、参数类型和顺序,不包括返回值类型 二、函数重载解析函数重载是 C++ 实现静态多态的基础机制,允许在同一作用域内定义多个同名函数,通过参数列表的差异进行区分。 重载的实现原理编译器在编译阶段会对重载函数进行名称修饰(Name Mangling),根据函数名和参数列表生成唯一的内部名称,因此重载函数在底层实际上拥有不同的标识符。 重载示例代码123456789101112131415161718192021222324252627282930313233343536373839#include <iostream...
派生类对象复制控制
一、复制控制的核心概念与场景复制控制机制是C++中处理对象创建、复制和销毁的核心手段。在继承体系中,当派生类对象被复制时,需要特别关注以下关键点: 复制场景 拷贝构造函数调用:当用已存在的对象初始化新对象时 赋值操作符调用:当用一个对象赋值给另一个对象时 析构函数调用:当对象生命周期结束时 典型问题 浅拷贝导致的指针悬挂(dangling pointer) 资源泄漏(resource leak) 自赋值(self-assignment)引发的异常 二、派生类复制的构造函数调用链12345678910111213class Base {public: Base() { /* 基类构造 */ } Base(const Base& other) { /* 基类拷贝构造 */ } ~Base() { /* 基类析构 */ }};class Derived : public Base {public: Derived() : Base() { ...
Python条件语句:if-elif-else分支结构
Python的条件语句用于根据不同的条件执行不同的代码块。本文将详细介绍Python中if、elif、else条件语句的使用方法。 一、基本语法1. 简单的if语句1234x = 10if x > 5: print("x大于5") # 输出:x大于5 2. if-else语句123456x = 3if x > 5: print("x大于5")else: print("x不大于5") # 输出:x不大于5 3. if-elif-else语句12345678910score = 85if score >= 90: print("优秀")elif score >= 80: print("良好") # 输出:良好elif score >= 70: print("中等")else: print("及格") 二、Python与C++的对比1. 条件表达式C++: 1234...
C++ 继承机制中的类型转换
一、对象赋值的双向可行性分析1.1 基类到派生类的转换 隐式转换: 不允许直接赋值(如 Base b = d;) 显式转换: 需使用构造函数或类型转换运算符 123456789101112class Base {public: Base() {} explicit Base(int val) : data(val) {}private: int data;};class Derived : public Base {public: Derived(int val) : Base(val) {}}; 内存影响: 派生类对象包含基类数据成员,赋值操作不会改变大小,但会丢失派生类特有数据 1.2 派生类到基类的转换 隐式转换: 允许(如 Base b = d;) 显式转换: 可使用static_cast或构造函数 123Derived d;Base b = d; // 隐式转换Base& br = static_cast<...
Python全局变量:作用域与global关键字
在Python编程中,全局变量和局部变量的作用域是一个重要的概念。本文将详细介绍Python中全局变量的使用,以及如何通过global关键字在函数内部修改全局变量。 一、全局变量和局部变量1. 基本概念123456789101112# 全局变量global_var = 10def func(): # 局部变量 local_var = 20 print(f"Inside function: global_var = {global_var}") print(f"Inside function: local_var = {local_var}")func()print(f"Outside function: global_var = {global_var}")# print(local_var) # NameError: name 'local_var' is not defined 2. 作用域规则12345678...
C++ virtual 继承机制详解(非多态场景)
一、virtual 继承的核心作用在C++中,virtual关键字用于解决多重继承时的菱形继承问题。当多个派生类共享同一基类时,如果不使用虚继承,会导致基类对象被多次实例化,造成内存浪费和指针混淆。 1.1 问题场景考虑经典菱形继承结构: 12345678910111213141516class A {public: int a;};class B : virtual public A {public: int b;};class C : virtual public A {public: int c;};class D : public B, public C {}; 在这种情况下,D对象会包含两个A子对象(一个来自B,一个来自C),导致: 内存重复占用(每个A子对象占用相同内存空间) 指针访问歧义(需要明确使用B::a或C::a) 1.2 解决方案通过在继承声明中添加virtual关键字,可以确保基类A仅被实例化一次: 12345678910111213141516clas...
Python函数副作用:返回值与状态变更
在Python编程中,理解函数副作用(Side Effects)是非常重要的。副作用是指函数在执行过程中,除了返回值之外,对外部状态产生的任何改变。理解副作用有助于编写更清晰、更安全的代码。 一、什么是函数副作用1. 基本定义副作用包括但不限于: 修改全局变量 修改传入的参数 输入/输出操作(打印、读取文件、网络通信等) 修改数据结构 抛出异常 2. 无副作用函数示例1234567# 无副作用:纯函数def add(a, b): return a + bresult = add(3, 5)print(result) # 输出:8# 函数外部没有任何改变 3. 有副作用函数示例12345678910# 有副作用:修改全局变量counter = 0def increment(): global counter counter += 1 return counterprint(increment()) # 输出:1print(counter) # 输出:1(全局变量被修改) 二、常见的副作用场景1. 修改全局变量123456789...
C++ 关联容器(map 与 set)解析
一、关联容器的底层数据结构特性C++ 标准库中的map和set均属于关联容器,其底层实现基于红黑树(Red-Black Tree)—— 一种自平衡的二叉搜索树。这种数据结构具有以下核心特性: 有序性:元素按照键值的比较规则进行排序存储 自平衡性:通过特定的旋转和着色操作,保证树的高度始终保持在 O (log n) 级别 迭代效率:支持高效的顺序访问和范围查询 红黑树的平衡机制确保了所有基本操作(插入、删除、查找)都能在O(log n) 的时间复杂度内完成,这使得关联容器在需要频繁查找和有序遍历的场景中表现优异。 二、map 与 set 的存储机制差异虽然map和set共享相同的底层实现机制,但它们的存储方式存在本质区别: 特性 set map 存储内容 仅存储键(key) 存储键值对(key-value) 元素唯一性 键值唯一,不允许重复 键值唯一,不允许重复 访问方式 只能通过键访问元素 可通过键访问对应的值 模板参数 std::set<Key, Compare, Allocator> std::map<Key, Value,...
C++ Map 容器
一、核心数据结构:红黑树C++ 标准库中std::map的底层实现采用红黑树(Red-Black Tree),这是一种自平衡的二叉搜索树(BST)。红黑树通过特定的规则保证树的高度始终维持在 O (log n) 级别,从而确保各种操作的高效性。 1具体见前一篇 C++ 标准库中的 set 容器 二、map 容器的核心组件2.1 迭代器实现std::map的迭代器是双向迭代器,其实现本质上是红黑树节点的指针封装,并提供了遍历树的操作。 2.2 内存管理机制std::map通常使用内存池(memory pool)或分配器(allocator)管理节点内存,而非频繁调用new和delete: 采用 slab 分配策略,预先分配一批节点内存 节点释放时不直接归还给系统,而是放入空闲列表 下次分配时优先从空闲列表获取,减少系统调用开销 三、核心操作实现3.1 插入操作(insert)插入操作流程: 按照二叉搜索树规则找到插入位置 插入新节点并标记为红色 执行修复操作(rebalance),可能包括: 变色(recoloring) 旋转(rotation):左旋、...
Python函数定义:def关键字与缩进规则
Python的函数定义使用def关键字,与C++等语言不同,Python不使用大括号来标记函数体,而是依靠缩进来区分代码块。本文将详细介绍Python函数定义的方式和特点。 一、Python函数定义的基本语法1. 基本结构123456# Python函数定义def greet(): print("Hello, World!")# 调用函数greet() # 输出:Hello, World! 2. 带参数的函数123456789101112# 带参数的函数def greet(name): print(f"Hello, {name}!")greet("Alice") # 输出:Hello, Alice!# 多个参数def add(a, b): return a + bresult = add(3, 5)print(result) # 输出:8 3. 默认参数值123456789# 默认参数def greet(name, greeting="Hello"): ...
Python数值处理:round()函数四舍五入机制
Python的round()函数是处理浮点数四舍五入的重要工具。本文将详细介绍round()函数的使用方法以及常见的精度问题。 一、round()函数的基本用法1. 基本语法1round(number, ndigits) number:要四舍五入的数字 ndigits:保留的小数位数(可选,默认为0) 2. 基本示例12345# 基本四舍五入print(round(3.14159)) # 输出:3print(round(3.5)) # 输出:4print(round(3.14159, 2)) # 输出:3.14print(round(3.14159, 4)) # 输出:3.1416 3. 负数四舍五入1234567# 负数四舍五入到整数print(round(-3.5)) # 输出:-4print(round(-3.4)) # 输出:-3# 负数四舍五入到小数位print(round(-3.14159, 2)) # 输出:-3.14print(round(-3.14159, 3)) # 输出:-3.1...

