当前位置: 首页 > news >正文

python学习day29

DAY 29 复习日

知识点回顾

  1. 类的装饰器
  2. 装饰器思想的进一步理解:外部修改、动态
  3. 类方法的定义:内部定义和外部定义

作业:复习类和函数的知识点,写下自己过去29天的学习心得,如对函数和类的理解,对python这门工具的理解等,未来再过几个专题部分我们即将开启深度学习部分。

1.函数的基本写法:

def function_name(parameter1, parameter2, ...):

    """

    Docstring: 描述函数的功能、参数和返回值 (可选但强烈推荐)

    """

    # 函数体: 实现功能的代码

    # ...

    return value # 可选,用于返回结果

2.函数的参数类型(位置参数、默认参数、可变数量参数):

参数有以下类型:

- 位置参数 (Positional Arguments): 调用时按顺序匹配。比如def describe_pet(animal_type, pet_name):中的animal_type, pet_name就是位置参数

- 默认参数值 (Default Parameter Values): 定义函数时给参数指定默认值,调用时如果未提供该参数,则使用默认值。def describe_pet_default(pet_name, animal_type="狗"):这其中的animal_type="狗"就是默认参数。

- 可变数量参数 (*args 和 **kwargs):

    - *args: 将多余的位置参数收集为一个元组。def make_pizza(size, *toppings):中的*toppings就是一个*args

    - **kwargs: 将多余的关键字参数收集为一个字典。def build_profile(first_name, last_name, **user_info):中的**user_info就是一个**kwargs

*args 和 **kwargs 的核心目的是让函数能够接收不定数量的参数,并以元组和字典的形式在函数内部进行处理。也就是说 当位置参数用完了 就自动变成*args,当关键词参数用完了 就自动变成**kwarges

process_data(101, "Alice", "vip", "new_user", location="USA", age=30)
# ID: 101
# Name: Alice
# Tags (*args): ('vip', 'new_user')  <-- "vip", "new_user" 是多余的位置参数,被 *tags 收集
# Status: pending                    <-- status 使用默认值,因为调用中没有 status=...
# Details (**kwargs): {'location': 'USA', 'age': 30} <-- location 和 age 是多余的关键字参数,被 **details 收集

3.装饰器:

装饰器的本质是一个高阶函数,它接收一个函数作为参数,并返回一个新函数来替代原函数。这个新函数需要:

1. 保留原函数的调用方式(参数和返回值)。

2. 在原函数执行前后添加额外逻辑(如计时、日志等)。

因此,我们需要在装饰器内部定义一个新函数来实现这些功能。

# 继续定义判断质数的函数
def is_prime(num):"""判断一个数是否为素数"""if num < 2:return Falseelif num == 2:return Trueelse:for i in range(2, num):if num % i == 0:return Falsereturn True# 装饰器的标准写法
@display_time
def prime_nums(): # 这2行是一个整体"""找出2到10000之间的所有素数并打印"""for i in range(2, 10000):if is_prime(i):print(i)prime_nums()
# 执行时间每次都会变,但是变动不大,一般计算稳定的执行时间我们都是重复1000遍,然后取平均

其中display_time是一个记录时间的装饰器

import time# 定义一个装饰器
def display_time(func):def wrapper(): # 定义一个内部函数,在装饰器中wrapper函数是一个常用的函数名,并非强制,约定俗成的start_time = time.time()func()  # 直接调用原函数(无参数),这里的func()是指装饰器需要修饰的函数,在这里是prime_nums()end_time = time.time()print(f"执行时间: {end_time - start_time} 秒")return wrapper # return wrapper是返回函数对象,如果是return wrapper()则是立即执行wrapper函数

4.类的定义:

一个常见的类的定义包括了:

1. 关键字class

2. 类名

3. 语法固定符号冒号(:)

4. 一个初始化函数__init__(self)  

注意:注意:init左右各有两个下划线__,需要传入self这个特殊的参数。

比如:

class Teacher: 

  def __init__(self):

5.类的初始化方法:

初始化方法又叫构造方法、特殊方法

类有2种方法

1. 初始化方法

2. 普通方法

初始化方法:

class Teacher: def __init__(self): self.name = "Susan" self.subject = "English"self.age = 33

普通方法:

def function_name(parameter1, parameter2, ...):"""Docstring: 描述函数的功能、参数和返回值 (可选但强烈推荐)"""# 函数体: 实现功能的代码# ...return value # 可选,用于返回结果

6.类的继承:

在面向对象编程中,继承允许一个类(子类)继承另一个类(父类)的属性和方法,从而实现代码复用和功能扩展。子类可以:

1. 复用父类的代码(无需重新实现)。

2. 重写父类的方法(修改或增强功能)。

3. 添加新的方法和属性(扩展功能)。

# 先沿用之前定义的teacher类
class Teacher:def __init__(self, name, subject, age):self.name = nameself.subject = subjectself.age = agedef teach_lesson(self):print(f"{self.name}正在教{self.subject}。")def criticize(self, student_name):print(f"{self.name}正在批评{student_name}。")# 继承 Teacher 类,起名特级教师
class MasterTeacher(Teacher): # 1. 继承需要在括号中指定父类def __init__(self, name, subject, age, experience_years):# 2. 继承的时候需要调用父类的构造方法,所以需要传入父类的参数,同时也可以传入自己的参数# 调用父类的构造方法初始化基本属性super().__init__(name, subject, age) # 3. 调用父类的构造方法,这里的super()是一个内置函数,返回父类的实例# 4. 此时子类自动拥有了父类的属性和方法# 添加子类特有的属性self.experience_years = experience_years # 5. 子类特有的属性可以在这里定义# 重写父类方法,增强功能-----如果子类定义了与父类同名的方法,子类实例会优先调用子类的方法。def teach_lesson(self): # 6. 重写父类的方法print(f"{self.name}(特级教师)正在用高级方法教授{self.subject}。")# 新增子类特有的方法def give_lecture(self, topic): print(f"{self.name}正在举办关于{topic}的讲座。")# 创建子类实例
master = MasterTeacher("王教授", "数学", 45, 20)# 调用继承的方法
master.teach_lesson()     # 调用重写的父类的方法
master.criticize("李同学")  # 调用父类的方法,如果不修改方法,则可以直接继承父类的方法# 调用子类特有的方法
master.give_lecture("微积分")  # 调用子类新增的方法

7.类的装饰器:

类也有修饰器,他的逻辑类似:接收一个类,返回一个修改后的类。例如

1. 添加新的方法或属性(如示例中的 log 方法)。

2. 修改原有方法(如替换 __init__ 方法,添加日志)。

3. 甚至可以返回一个全新的类(继承或组合原类)。

通过类装饰器,可以在不修改类内部代码的情况下,为多个类统一添加功能(如日志、统计)

同样是语法糖的写法:第一步先定义装饰器,第二步应用装饰器

函数装饰器写法:

#函数装饰器的写法
# 定义一个装饰器
def display_time(func):def wrapper(): # 定义一个内部函数,在装饰器中wrapper函数是一个常用的函数名,并非强制,约定俗成的start_time = time.time()func()  # 直接调用原函数(无参数),这里的func()是指装饰器需要修饰的函数,在这里是prime_nums()end_time = time.time()print(f"执行时间: {end_time - start_time} 秒")return wrapper# 继续定义判断质数的函数
def is_prime(num):"""判断一个数是否为素数"""if num < 2:return Falseelif num == 2:return Trueelse:for i in range(2, num):if num % i == 0:return Falsereturn True# 装饰器的标准写法
@display_time
def prime_nums(): # 这2行是一个整体"""找出2到10000之间的所有素数并打印"""for i in range(2, 10000):if is_prime(i):print(i)prime_nums()

类装饰器写法:

# 定义类装饰器:为类添加日志功能
def class_logger(cls):# 保存原始的 __init__ 方法original_init = cls.__init__def new_init(self, *args, **kwargs):# 新增实例化日志print(f"[LOG] 实例化对象: {cls.__name__}")original_init(self, *args, **kwargs)  # 调用原始构造方法# 将类的 __init__ 方法替换为新方法cls.__init__ = new_init# 为类添加一个日志方法(示例)def log_message(self, message):print(f"[LOG] {message}")cls.log = log_message  # 将方法绑定到类,这是一种将外部函数添加为类的属性的方法return cls# 定义简单打印类,应用装饰器
# 同样是语法糖的写法
@class_logger
class SimplePrinter:def __init__(self, name):self.name = name  # 构造方法:初始化名称def print_text(self, text):"""简单打印方法"""print(f"{self.name}: {text}")# 使用示例
printer = SimplePrinter("Alice")  # 实例化时触发装饰器的日志
printer.print_text("Hello, World!")  # 调用普通方法
printer.log("这是装饰器添加的日志方法")  # 调用装饰器新增的方法

实际上,定义类的方法,有2类写法

1. 在类定义内部直接写方法,这是静态方法,一般定义类都这么完成。

2. 在类定义外部定义方法,然后把方法赋值给类的属性---这是一种动态方法,常在装饰器中使用,可以再外部修改类的方法。

注意到其中的cls.log = log_message 这行代码,他把外部的函数赋值给了类的新定义的属性,这里我们介绍这种写法,这就是外部赋值。

@浙大疏锦行

相关文章:

  • Neovim 如何安装和配置缩进标识插件 indent-blankline.nvim
  • 贝塞尔曲线原理
  • Manus vs Lovart:AI Agent技术深度解析与实战指南
  • MyBatis框架(入门)
  • Arduino UNO采集血压/心率/血氧/体温等数据传输到Blinker云平台 手机APP显示数据
  • 【深度学习基础】从感知机到多层神经网络:模型原理、结构与计算过程全解析
  • 计算机系统---TPU(张量处理单元)
  • Java——创建多线程的四种方式
  • 【大模型面试每日一题】Day 22:若训练中发现Loss突然剧烈波动(Spike),可能有哪些原因?如何定位和修复?
  • MySQL之储存引擎和视图
  • C语言:在 Win 10 上,gcc 如何编译 调用 Tcl/Tk 的C程序
  • Hugo安装Stack主题
  • DAY 4 缺失值的处理
  • Spring ioc和Aop
  • 【ROS2】虚拟机使用fishros脚本一键安装humble
  • Codeforces 1017 Div4(ABCDEFG)
  • 翻译:20250518
  • 【Python数据处理系列】输入txt,读取特定字符转换成特定csv数据并输出
  • C# String 格式说明符
  • C++模板进阶使用技巧
  • 交响4K修复版《神女》昨晚上演,观众听到了阮玲玉的声音
  • “80后”南京大学天文与空间科学学院教授施勇加盟西湖大学
  • 经济日报金观平:促进信贷资金畅达小微企业
  • 北京韩美林艺术馆党支部书记郭莹病逝,终年40岁
  • 特朗普指控FBI前局长“暗示刺杀总统”,“8647”藏着什么玄机?
  • 李伟任山东省委常委、省纪委书记