Guru of the Week #5:虚函数的重新定义

本文围绕C++虚函数重新定义展开,通过一段老源码示例,分析了代码风格问题,如main函数声明、基类析构函数、继承类函数覆盖与重载、参数缺省值等。还探讨了程序实际运行结果与作者期望的差异,强调了理解虚函数机制和遵循编程原则的重要性。

作者:Hub Sutter
译者:plpliuly

/*此文是译者出于自娱翻译的GotW(Guru of the Week)系列文章第5篇,原文的版权是属于Hub Sutter(著名的C++专家,"Exceptional C++"的作者)。此文的翻译没有征得原作者的同意,只供学习讨论。——译者
*/

#5 虚函数的重新定义 (1997年5月14提出)
难度: 6/10

    虚函数是C++的一个基本特性,对不对?如果你能够回答下面的问题,那说明你确实已经掌握.

问题:
    假设你正在看一些很老的源码,其中有一段如下的代码,作者已经不知其人了.这个作者写这段代码好像仅仅是为了验证C++特性的工作机理而做的小实验.作者期望这个程序打印出什么样的结果呢,可实际上的输出结果又是怎样呢?
    #include <iostream>
    #include <complex>
    using namespace std;

    class Base {
    public:
        virtual void f( int ) {
            cout << "Base::f(int)" << endl;
        }

        virtual void f( double ) {
            cout << "Base::f(double)" << endl;
        }

        virtual void g( int i = 10 ) {
            cout << i << endl;
        }
    };

    class Derived: public Base {
    public:
        void f( complex<double> ) {
            cout << "Derived::f(complex)" << endl;
        }

        void g( int i = 20 ) {
            cout << "Derived::g() " << i << endl;
        }
    };

    void main() {
        Base    b;
        Derived d;
        Base*   pb = new Derived;

        b.f(1.0);
        d.f(1.0);
        pb->f(1.0);

        b.g();
        d.g();
        pb->g();

        delete pb;
    }

答案:

    首先,一些代码风格问题:
   
    1.void main()
    
    这并不是一个main函数的合法声明,尽管很多编译器都允许这样做.应该使用"int main()"或者"int main(int argc,char* argv[])".
    但是,请注意此处并不需要返回结果(尽管给外面的调用者返回一个报告错误的返回值是书写函数的好风格)...如果main没有返回语句,效果就和"return 0;"一样.

   2.delete pb;

   这看起来好像没有什么不妥,但是只有当Base类提供了虚拟析构函数才会没事.否则,通过一个没有虚拟析构函数的基类的指针来释放继承类的对象是危险的,因为,你能得到的结果就是出错.(译者注:至少是内存泄漏)
   [原则]将基类的析构函数定义为虚拟函数

   3.Derived::f( complex<double> )

   Derived类并没有重载Base::f...它仅仅是覆盖了它们.此处的区别是非常重要的,因为这意味着Base::f(int)和Base::f(double)对Derived类是不可见的!(注意:某些流行的编译器甚至对此连警告错误都不给.)
   [原则]当你在继承类中定义一个与基类中函数同名的函数,如果你不想将基类中的函数隐藏掉,你必须用"using"指示语句来将基类中的函数纳入继承类的scope中来,以便对继承类可见.

   4.Derived::g( int i = 10 )

   除非你真的想让别人迷糊,否则不要在继承类中改变函数的参数缺省值.(一般来讲,尽量采用函数重载来代替参数缺省值的改变是一个不错的方法.)当然,这是合法的C++语句,结果也是可预知的,但是,不要这样做.你可以看看下面的讨论中这样做会怎样的让别人迷惑.
  [原则]决不要改变基类中函数的参数缺省值.

   讨论完几个主要的代码风格问题后,让我们切入正题来看看程序是不是会如代码作者所希望的那样运行:

   void main() {
        Base    b;
        Derived d;
        Base*   pb = new Derived
;

        b.f(1.0);
   没问题.调用Base::f( double ).
   
        d.f(1.0);
  
此处调用Derived::f( complex<double> ).为什么?记住Derived类没有声明"using Base::f;",因此Base::f( int )和Base::f( double )不会被调用.
   代码作者也许希望调用后者,但是此处连一个编译错误都不会给出.comlex<double>有一个对于double类型的隐式转换(*),因此编译器将上面的语句看作是Derived::f( complex<double>(1.0) ).
 
   (*)根据目前的C++标准草案,这个转换构造函数不是explicit的

     pb->f( 1.0 );
  
有趣的是,尽管Base* pb指向一个Derived的对象,此处调用的是Base::f( double ),因为编译器的重载解释(overload resolution)是根据静态数据类型(此处就是Base),而不是动态类型(此处为Derived).
 
     b.g();
  
这条语句将打印"10",因为它调用了Base::g( int ),其参数的缺省值是10.没有疑问.

     d.g();
   
这条语句将打印"Derived::g()20",因为它调用了Derived::g( int ),其参数的缺省值是20.同样没疑问.

     pb->g();
  
这条语句将打印"Derived::g()10"...这可能会让你吓一大跳,百思不解.但编译器做得是很对的.需要记住的是,和函数重载一样,参数缺省值是从对象的静态类型(此处是Base)解释出来的,因此此处的参数缺省值取10.然而,此处的函数碰巧是虚函数,因此实际被调用的函数是由对象的动态类型(此处是Derived)决定的.
  
   如果你完全理解了上面的最后几段解释,你也就理解了我们今天讨论的问题.祝贺你.
 
      delete pb;
      }
  
此处的delete显然会让对象只是部分的释放,导致内存错误...看看上面讨论的虚拟构造函数就明白了.
----
(结束)

# ==================== Python函数基础课程 ==================== """ 📚 本课程将系统讲解Python函数的核心知识,涵盖以下内容: 1. 函数基础概念:什么是函数?为什么使用函数? 2. 函数定义与使用:基础函数、带返回值函数、参数类型详解 3. 函数作用域与特性:全局/局部变量、闭包、递归 4. 函数返回类型详解:基本类型、容器类型、函数类型、生成器 5. 函数进阶特性:高阶函数、装饰器、文档与注解、错误处理 6. 生成器与迭代器:迭代器基础、生成器函数、数据处理管道 7. 综合应用:电商折扣计算、用户输入处理、数据分析管道、分页生成器 """ # ==================== 函数基础概念 ==================== """ 1. 什么是函数? 函数是组织好的、可重复使用的代码块,用于执行特定任务 - 接收输入参数 → 处理逻辑 → 返回输出结果 - 提高代码复用性、可读性和可维护性 """ # 示例1:简单函数定义与调用 def welcome_message(name: str) -> str:# 类型注解,告诉别人你要返回啥类型 """欢迎消息函数(返回字符串)""" # 函数文档字符串 return f"您好,{name}!欢迎使用Python函数教学" # 返回格式化字符串 # 调用函数并打印结果 print(welcome_message("张三")) # 输出:您好,张三!欢迎使用Python函数教学 """ 2. 为什么使用函数? 函数在编程中有三大核心价值: 1. 代码复用:避免重复编写相同代码 2. 模块化:将复杂问题分解为简单函数 3. 抽象封装:隐藏实现细节,暴露清晰接口 """ # 示例2:函数复用价值(返回浮点数) def calculate_area(radius: float) -> float:# """计算圆面积(返回浮点数)""" # 函数文档字符串 return 3.14 * radius ** 2 # 使用圆面积公式计算 # 复用计算函数 print(f"半径3的圆面积: {calculate_area(3)}") # 计算并打印半径3的圆面积 print(f"半径5的圆面积: {calculate_area(5)}") # 计算并打印半径5的圆面积 print(f"半径10的圆面积: {calculate_area(10)}") # 计算并打印半径10的圆面积 # 示例3:函数作为模块化工具(返回元组) def calculate_bmi(weight_kg: float, height_m: float) -> tuple: """计算BMI并返回结果和分类(返回元组)""" bmi = weight_kg / (height_m ** 2) # 计算BMI值 # 根据BMI值确定分类 category = "偏瘦" if bmi < 18.5 else "正常" if bmi < 24 else "超重" return bmi, category # 返回包含两个值的元组 # 使用示例 bmi, status = calculate_bmi(70, 1.75) # 计算BMI print(f"BMI: {bmi:.1f}, 状态: {status}") # 输出: BMI: 22.9, 状态: 正常 # ==================== 函数定义与使用 ==================== # 1. 基础函数定义(无返回值) def greet(name: str) -> None: """向用户打招呼(无返回值)""" # 函数文档字符串 print(f"Hello, {name}!") # 打印问候语 # 函数调用示例 greet("Alice") # 调用greet函数并传入参数"Alice" # 2. 带返回值的函数(返回整数) def add(a: int, b: int) -> int: """返回两个数的和(返回整数)""" # 函数文档字符串 return a + b # 返回a和b的和 # 调用函数并存储结果 result = add(3, 5) # 调用add函数计算3+5 print(f"3+5的结果是{result}") # 打印计算结果 # 3. 参数类型详解(返回元组) def complex_func(a: int, b: int = 2, *args: any, **kwargs: any) -> tuple: """ 带类型注解的复杂函数(返回元组) 参数类型演示: a: 必选参数(整数) b: 默认参数(整数,默认为2) *args: 可变位置参数(任意类型) **kwargs: 可变关键字参数(任意类型) """ print(f"a = {a} (类型: {type(a).__name__})") # 打印必选参数a的值和类型 print(f"b = {b} (类型: {type(b).__name__})") # 打印默认参数b的值和类型 # 遍历可变位置参数 for i, arg in enumerate(args): # 使用enumerate获取索引和值 print(f"args[{i}] = {arg} (类型: {type(arg).__name__})") # 打印每个位置参数及其类型 # 遍历可变关键字参数 for key, value in kwargs.items(): # 遍历关键字参数字典 print(f"{key} = {value} (类型: {type(value).__name__})") # 打印每个关键字参数及其类型 return a + b, a * b # 返回两个计算结果组成的元组 # 混合参数调用示例 res = complex_func(3, 4, 5, 6, name="Bob", age=25) # 调用函数并传入多种类型参数 print(f"返回结果: {res} (类型: {type(res).__name__})") # 打印函数返回结果及其类型 # 4. 仅关键字参数函数(返回字典) def create_user(*, username: str, email: str, is_admin: bool = False) -> dict: """创建用户账户(返回字典)""" return {"username": username, "email": email, "admin": is_admin} # 返回用户信息字典 # 必须使用关键字方式调用 user = create_user(username="tech_guru", email="guru@example.com") # 创建用户 print(user) # 输出: {&#39;username&#39;: &#39;tech_guru&#39;, &#39;email&#39;: &#39;guru@example.com&#39;, &#39;admin&#39;: False} # ==================== 函数作用域与特性 ==================== # 1. 作用域示例(全局变量与局部变量) global_var = "全局变量" # 定义全局变量 def scope_test() -> int: """作用域测试函数(返回整数)""" # 函数文档字符串 local_var = "局部变量" # 定义局部变量 print(f"访问全局变量: {global_var}") # 在函数内访问全局变量 global another_global # 声明要修改全局变量 another_global = "在函数中定义的全局变量" # 修改全局变量 power = lambda x: x ** 2 # 定义lambda函数(匿名函数) return power(5) # 调用lambda函数并返回结果 # 调用函数并打印结果 print(f"lambda结果: {scope_test()}") # 打印lambda函数计算结果 print(f"新全局变量: {another_global}") # 打印修改后的全局变量 # 2. 闭包作用域示例(返回函数) def counter_factory(initial: int = 0) -> callable: """创建计数器闭包(返回函数)""" count = initial # 闭包内部状态 def increment() -> int: """内部计数器函数(返回整数)""" nonlocal count # 声明使用外部变量 count += 1 # 修改闭包状态 return count # 返回当前计数值 return increment # 返回内部函数 # 使用闭包示例 counter1 = counter_factory(10) # 创建初始值为10的计数器 print(counter1()) # 输出: 11 print(counter1()) # 输出: 12 # 3. 递归函数示例(返回整数) def factorial(n: int) -> int: """计算阶乘的递归函数(返回整数)""" # 函数文档字符串 if n == 0: # 递归终止条件 return 1 # 0的阶乘是1 return n * factorial(n - 1) # 递归调用自身 # 计算并打印5的阶乘 print(f"5! = {factorial(5)}") # 输出: 5! = 120 # ==================== 函数返回类型详解 ==================== """ Python函数支持返回多种类型: 1. 基本类型:int, float, str, bool, None 2. 容器类型:list, tuple, dict, set 3. 函数类型:闭包函数、装饰器函数 4. 生成器:使用yield关键字 5. 特殊类型:None(无返回值) """ # 1. 返回列表 def get_even_numbers(n: int) -> list: """获取前n个偶数(返回列表)""" return [i * 2 for i in range(1, n + 1)] # 返回偶数列表 print(f"前5个偶数: {get_even_numbers(5)}") # 输出: [2, 4, 6, 8, 10] # 2. 返回字典 def create_person(name: str, age: int) -> dict: """创建人员信息字典(返回字典)""" return {"name": name, "age": age} # 返回人员信息字典 print(f"人员信息: {create_person(&#39;王五&#39;, 30)}") # 输出: {&#39;name&#39;: &#39;王五&#39;, &#39;age&#39;: 30} # 3. 返回函数 def multiplier_factory(factor: int) -> callable: """创建乘法器函数(返回函数)""" def multiply(x: int) -> int: return x * factor # 使用闭包变量 return multiply # 返回内部函数 double = multiplier_factory(2) # 创建乘以2的函数 print(f"5的双倍: {double(5)}") # 输出: 10 # 4. 返回生成器 def fibonacci(n: int) : """生成斐波那契数列(返回生成器)""" a, b = 0, 1 # 初始化前两个值 for _ in range(n): # 生成n个数 yield a # 生成当前值 a, b = b, a + b # 更新下一个值 print("斐波那契数列:", list(fibonacci(10))) # 输出前10个斐波那契数 # ==================== 函数进阶特性 ==================== # 1. 高阶函数示例(函数作为参数) def apply_to_list(func: callable, data: list) -> list: """将函数应用到列表每个元素(返回列表)""" return [func(x) for x in data] # 对每个元素应用函数 # 使用高阶函数 numbers = [1, 2, 3, 4] print(apply_to_list(lambda x: x * 2, numbers)) # 输出: [2, 4, 6, 8] # 2. 装饰器示例(返回包装函数) def timing_decorator(func: callable) -> callable: """测量函数执行时间的装饰器(返回函数)""" def wrapper(*args, **kwargs): import time # 导入时间模块 start = time.time() # 记录开始时间 result = func(*args, **kwargs) # 调用原始函数 end = time.time() # 记录结束时间 # 打印执行时间(保留6位小数) print(f"{func.__name__} 执行耗时: {end - start:.6f}秒") return result # 返回原始函数的结果 return wrapper # 返回包装函数 @timing_decorator # 应用装饰器 def calculate_sum(n: int) -> int: """计算1到n的和(返回整数)""" return sum(range(1, n + 1)) # 使用内置sum函数求和 # 调用装饰后的函数 print(f"1到1000000的和: {calculate_sum(1000000)}") # 计算并打印结果 # 3. 函数文档和注解 def format_user_info(name: str, age: int, email: str = "") -> str: """ 格式化用户信息(返回字符串) 参数: name: 用户名 (字符串) age: 用户年龄 (整数) email: 用户邮箱 (字符串, 可选) 返回: 格式化后的用户信息字符串 """ email_info = f", 邮箱: {email}" if email else "" # 处理邮箱信息 return f"姓名: {name}, 年龄: {age}{email_info}" # 返回格式化字符串 # 使用函数 print(format_user_info("李四", 28, "lisi@example.com")) # 调用函数并打印结果 print("函数注解:", format_user_info.__annotations__) # 打印函数类型注解 print("函数文档:", format_user_info.__doc__) # 打印函数文档字符串 # 4. 错误处理增强(返回字符串或None) def safe_file_read(filename: str) -> str : """安全读取文件内容(返回字符串或None)""" try: with open(filename, &#39;r&#39;, encoding=&#39;utf-8&#39;) as file: # 安全打开文件 return file.read() # 返回文件内容 except FileNotFoundError: # 处理文件不存在异常 print(f"错误: 文件 {filename} 不存在") # 打印错误信息 except Exception as e: # 处理其他异常 print(f"读取文件时出错: {str(e)}") # 打印错误详情 return None # 异常时返回None # 测试文件读取 print(safe_file_read("example.txt")) # 尝试读取不存在的文件 # ==================== 生成器与迭代器 ==================== # 1. 迭代器基础示例 print("\n迭代器示例:") # 打印标题 numbers = [10, 20, 30, 40, 50] # 创建列表 num_iter = iter(numbers) # 创建迭代器 print(next(num_iter)) # 输出: 10 (获取第一个元素) print(next(num_iter)) # 输出: 20 (获取第二个元素) print(next(num_iter)) # 输出: 30 (获取第三个元素) # 2. 生成器函数示例(返回生成器) def countdown(n: int) : """倒计时生成器(返回生成器)""" # 函数文档字符串 while n > 0: # 循环直到n为0 yield n # 生成当前值 n -= 1 # 值减1 print("\n倒计时生成器:") # 打印标题 for num in countdown(5): # 遍历生成器 print(num, end=" ") # 输出: 5 4 3 2 1 # 3. 文件读取生成器(返回生成器) def read_large_file(file_path: str) : """逐行读取大文件(返回生成器)""" # 函数文档字符串 with open(file_path, &#39;r&#39;, encoding=&#39;utf-8&#39;) as file: # 安全打开文件 for line in file: # 逐行读取 yield line.strip() # 生成去除空白符的行 # 创建测试文件 with open(&#39;test_file.txt&#39;, &#39;w&#39;) as f: # 打开文件用于写入 f.write("第一行\n第二行\n第三行") # 写入三行内容 print("\n\n文件内容:") # 打印标题 file_reader = read_large_file(&#39;test_file.txt&#39;) # 创建文件读取生成器 for line in file_reader: # 遍历生成器 print(line) # 打印每一行内容 # 4. 数据处理管道(返回生成器) def data_pipeline(data: list) : """数据处理管道(返回生成器)""" # 函数文档字符串 # 过滤偶数 → 平方转换 → 结果输出 filtered = (x for x in data if x % 2 == 0) # 生成器过滤偶数 transformed = (x ** 2 for x in filtered) # 生成器计算平方 return transformed # 返回处理后的生成器 data = range(1, 11) # 创建1-10的数据 print("\n数据处理结果:") # 打印标题 for num in data_pipeline(data): # 遍历处理后的数据 print(num, end=" ") # 输出: 4 16 36 64 100 # ==================== 综合应用 ==================== # 1. 电商折扣计算函数(返回浮点数) def calculate_discount(price: float, user_type: str = "regular", *coupons: float) -> float: """ 计算商品最终价格(返回浮点数) 参数: price: 商品原价 user_type: 用户类型 (regular/vip/premium) *coupons: 优惠券折扣列表 """ # 用户折扣映射 discounts = {"regular": 0.0, "vip": 0.1, "premium": 0.2} # 计算最大优惠券折扣 coupon_discount = max(coupons) if coupons else 0 # 应用最高折扣 discount = max(discounts.get(user_type, 0), coupon_discount) final_price = price * (1 - discount) # 确保不低于成本价(7折) return max(final_price, price * 0.7) # 使用示例 print(f"\nVIP用户最终价格: ¥{calculate_discount(1000, &#39;vip&#39;):.2f}") # ¥900.00 print(f"高级用户+优惠券: ¥{calculate_discount(1000, &#39;premium&#39;, 0.15, 0.2):.2f}") # ¥700.00 # 2. 用户输入处理(无返回值) def process_user_input() -> None: """处理用户输入(无返回值)""" # 函数文档字符串 try: num = int(input("\n请输入一个数字: ")) # 获取用户输入并转换为整数 print(f"{num}的平方是{num ** 2}") # 计算并打印平方 print(f"{num}的立方是{num ** 3}") # 计算并打印立方 except ValueError: # 处理非数字输入 print("错误:请输入有效数字!") # 打印错误信息 finally: # 无论是否异常都会执行 print("输入处理完成") # 打印完成信息 # 调用函数处理用户输入 process_user_input() # 调用函数 # 3. 数据分析管道(返回生成器) def data_analysis_pipeline(data: list) : """数据分析管道(返回生成器)""" # 函数文档字符串 # 步骤1: 过滤有效数据 valid_data = (x for x in data if isinstance(x, (int, float))) # 生成器过滤数字 # 步骤2: 数据转换 # 计算最小值和最大值 min_val = min(x for x in data if isinstance(x, (int, float))) # 计算最小值 max_val = max(x for x in data if isinstance(x, (int, float))) # 计算最大值 # 创建归一化生成器 normalized = ((x - min_val) / (max_val - min_val) for x in valid_data) return normalized # 返回归一化后的生成器 # 测试数据 test_data = [10, 15, &#39;a&#39;, 20, 25, None, 30, 35] # 包含各种类型的数据 print("\n数据标准化结果:") # 打印标题 for value in data_analysis_pipeline(test_data): # 遍历处理结果 print(f"{value:.2f}", end=" ") # 输出: 0.00 0.20 0.40 0.60 0.80 1.00 # 4. 分页生成器示例(返回生成器) def paginate(data: list, page_size: int) : """分页生成器(返回生成器)""" # 函数文档字符串 for i in range(0, len(data), page_size): # 按页大小循环 yield data[i:i + page_size] # 生成一页数据 big_dataset = list(range(1, 21)) # 创建1-20的数据集 print("\n\n分页数据:") # 打印标题 for page in paginate(big_dataset, 5): # 分页遍历 print(page) # 打印每页数据 这是教学的py文件,评估下,教学顺序的合理性,不合理的地方修改下
最新发布
08-07
你提供的这份 Python 函数基础课程教学文件整体结构清晰、内容全面,涵盖了函数从基础到进阶的各个方面,尤其适合测试人员或初学者学习使用。但从**教学逻辑**和**学习路径**的角度来看,确实有一些**顺序可以优化**的地方,以提升学习的流畅性和理解效率。 --- ## ✅ 整体评价 | 项目 | 评价 | |------|------| | **结构完整性** | ✅ 非常完整,覆盖了函数的所有主要知识点 | | **示例丰富性** | ✅ 示例丰富,贴近实际应用(如测试、数据分析) | | **教学逻辑** | ⚠️ 部分内容顺序略显跳跃,适合优化 | | **可读性** | ✅ 注释和说明清晰,适合教学和自学 | --- ## 📌 存在的问题与建议 ### 1. **函数返回类型详解** 放得太早 - 当前位置:在“函数定义与使用”之后 - 问题:学生还没完全掌握函数定义和参数传递方式,就讲返回值类型,会增加认知负担。 - **建议**:将“函数返回类型详解”移到“函数定义与使用”之后、“函数进阶特性”之前,作为“函数返回值”小节,统一讲解。 ### 2. **函数进阶特性** 中的装饰器、高阶函数等内容过早 - 当前位置:在“函数返回类型”之后 - 问题:装饰器、高阶函数属于函数的高级用法,放在基础内容中间会打乱节奏。 - **建议**:将“函数进阶特性”统一放到“函数作用域与特性”之后,作为“函数高级特性”章节。 ### 3. **生成器与迭代器** 放得太早 - 当前位置:在“函数进阶特性”之后 - 问题:生成器是函数的高级用法之一,应该在理解函数返回值、yield关键字后再讲。 - **建议**:将“生成器与迭代器”放到“函数进阶特性”之后,作为“函数的高级用法”专题讲解。 --- ## ✅ 优化后的教学顺序建议 ### ✅ 推荐结构顺序(按认知路径): ```markdown # ==================== Python函数基础课程 ==================== ## 1. 函数基础概念 - 什么是函数? - 为什么使用函数? - 函数的三大核心价值 - 本课件内容大纲 ## 2. 函数定义与使用 - 基础函数定义与调用 - 带返回值的函数 - 参数类型详解(必选、默认、可变、关键字) - 仅关键字参数函数 ## 3. 函数作用域与特性 - 全局变量与局部变量 - lambda 表达式 - 闭包函数 - 递归函数 ## 4. 函数返回值详解 - 返回基本类型(int, str, bool) - 返回容器类型(list, dict, tuple) - 返回函数对象(闭包、工厂函数) - 返回生成器(yield 用法) ## 5. 函数进阶特性 - 高阶函数(map/filter/reduce) - 装饰器(@语法)与函数增强 - 函数类型注解与文档字符串 - 错误处理中的函数封装 ## 6. 生成器与迭代器(函数高级用法) - 迭代器基础 - 生成器函数与 yield - 生成器表达式 - 数据处理管道构建 ## 7. 综合应用案例 - 电商折扣计算函数 - 用户输入处理函数 - 数据分析管道构建 - 分页数据生成器 ``` --- ## ✅ 修改建议(代码文件结构调整) 你可以将原文件中的章节按如下顺序重新排列: ```python # ==================== Python函数基础课程 ==================== """ 📚 本课程将系统讲解Python函数的核心知识,涵盖以下内容: 1. 函数基础概念:什么是函数?为什么使用函数? 2. 函数定义与使用:基础函数、带返回值函数、参数类型详解 3. 函数作用域与特性:全局/局部变量、闭包、递归 4. 函数返回类型详解:基本类型、容器类型、函数类型、生成器 5. 函数进阶特性:高阶函数、装饰器、文档与注解、错误处理 6. 生成器与迭代器:迭代器基础、生成器函数、数据处理管道 7. 综合应用:电商折扣计算、用户输入处理、数据分析管道、分页生成器 """ # ==================== 函数基础概念 ==================== ... # ==================== 函数定义与使用 ==================== ... # ==================== 函数作用域与特性 ==================== ... # ==================== 函数返回类型详解 ==================== ... # ==================== 函数进阶特性 ==================== ... # ==================== 生成器与迭代器 ==================== ... # ==================== 综合应用 ==================== ... ``` --- ##
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值