Python入门到高级(知识点四)

0 阅读9分钟

📚 Python入门到高级(知识点四)


💡 关键知识点

一、函数

1. 函数的定义和调用

函数:提前组织好的,可以重复使用的,具有特定功能的代码段。

使用函数的好处

  • 提高代码复用性:避免重复编写相同的代码
  • 提高代码可读性:将复杂功能封装成函数,主逻辑更清晰
  • 便于维护:修改功能只需改函数内部,不影响调用处
# 需求:定义一个函数用于计算任意两个数的和
def get_sum(a, b):
    sum = a + b
    return sum

# 调用函数
print(get_sum(1, 2))  # 3
print(get_sum(2, 3))  # 5
print(get_sum(3, 4))  # 7

2. 全局变量与局部变量

变量类型定义位置作用范围说明
全局变量函数外部定义函数内外都能访问在整个文件中都可以使用
局部变量函数内部定义只能在所属函数内访问函数执行完毕后被销毁
# 定义函数
def show():
    # 局部变量:只能在所属函数内访问
    b = 100
    # 如果全局变量和局部变量同名,默认访问的是局部变量
    print(a)  # 10(访问全局变量)
    print(b)  # 100(访问局部变量)


# main:程序的入口
if __name__ == '__main__':
    # 全局变量:函数内外都能访问
    a = 10
    
    # 调用 show 函数
    show()
    
    # 打印全局变量
    print(a)  # 10
    
    # print(b)  # ❌ 报错!局部变量 b 只能在函数内访问

3.有 global 和没有 global 的区别

场景代码结果说明
没有 globala = 10(全局) def test():     a = 100(局部)全局 a 仍为 10函数内创建了新的局部变量,不影响全局变量
有 globala = 10(全局) def test():     global a     a = 100全局 a 变为 100 ✅函数内修改的是全局变量
# 先定义函数
def show():
    # TODO 函数内如何修改全局变量?
    # global关键字声明要求修改的是全局变量
    global a
    a = 100
    print(a)  # 100


# 再调用函数
# main:默认是程序的入口
if __name__ == '__main__':
    # 全局变量: 函数内外都能访问
    a = 10
    # 调研show函数
    show()
    # 打印全局变量
    print(a)  # 100
注意事项

💡 开发建议

  • 全局变量和局部变量同名时,函数内默认访问局部变量(就近原则)
  • 在函数内修改全局变量时,必须用 global 关键字声明
  • 如果不使用 global,Python 会把函数内的赋值当作创建新的局部变量
  • 尽量少用全局变量,过多使用会导致代码难以维护和理解

4. 函数的参数传递

参数类型说明特点
位置传参实参和形参按位置一一对应顺序和个数必须一致
关键字传参通过形参名指定传入的值个数必须一致,顺序无所谓
默认参数定义函数时提前设置默认值用户传参则用新值,不传则用默认值
可变参数 *args以元组形式接收任意多个位置参数可以接收任意数量的位置参数
可变参数 **kwargs以字典形式接收任意多个关键字参数可以接收任意数量的关键字参数

🧑‍💻 综合代码示例

# 1. 定义函数
def show1(name, age, weight):
    print(f"姓名:{name},年龄{age}岁,体重:{weight}kg")


def show2(name='张三', age=18, weight=66):
    print(f"姓名:{name},年龄{age}岁,体重:{weight}kg")


def show3(*args):
    print(args, type(args))


def show4(**kwargs):
    print(kwargs, type(kwargs))


def show5(*args, **kwargs):
    print("位置参数:", args)
    print("关键字参数:", kwargs)


# 2. 调用函数
if __name__ == '__main__':
    # 位置传参
    show1('张三', 18, 66)                    # 姓名:张三,年龄18岁,体重:66kg

    # 关键字传参
    show1(name='张三', age=18, weight=66)   # 姓名:张三,年龄18岁,体重:66kg

    # 默认参数
    show2()                                 # 姓名:张三,年龄18岁,体重:66kg
    show2('李四', 20, 70)                   # 姓名:李四,年龄20岁,体重:70kg

    # 可变参数 *args
    show3(1, 2, 3)                          # (1, 2, 3) <class 'tuple'>

    # 可变参数 **kwargs
    show4(a=1, b=2, c=3)                    # {'a': 1, 'b': 2, 'c': 3} <class 'dict'>

    # 组合使用
    show5(1, 2, 3, a=4, b=5, c=6)
    # 位置参数: (1, 2, 3)
    # 关键字参数: {'a': 4, 'b': 5, 'c': 6}

二、文件操作

1. 文件操作的两种方式

需求: 把当前目录下的test.txt读取到程序中,打印内容

方式1: 原始方式 必须手动关闭,否则浪费资源

# 打开文件
f = open('test.txt', mode='r', encoding='utf8')
# 读文件
data = f.read()
print(data)
# 关闭文件(节省资源)
f.close()

方式2: with方式(推荐) 自动关闭,无需手动

with open('test.txt', mode='r', encoding='utf8') as f:
    # 读文件
    data = f.read()
    print(data)

2. 文件备案

需求: 当前目录中的文件,图片,视频,音频等做个备份

模式说明用途
r读取文本文件.txt 等文本文件
w覆盖写数据到文本文件写文本文件(覆盖原内容)
a追加写数据到文本文件文本末尾追加内容
rb二进制读取文件 ✅读图片、视频、音频等
wb二进制覆盖写数据到文件 ✅写二进制文件(覆盖原内容)
ab二进制追加写数据到文件 ✅二进制文件末尾追加

💡 推荐使用二进制模式 rb / wb:适用于任何文件类型(图片、视频、音频、文本等),通用性最强。

方式1: 原始方式 必须手动关闭,否则浪费资源

# 打开文件
f_in = open('hm.jpg', mode='rb')
f_out = open('hm[备份1].jpg', mode='wb')
# 读写文件
data = f_in.read()
f_out.write(data)
print('文件备份成功!')
# 关闭文件(节省资源)
f_out.close()
f_in.close()

⚠️ 缺点:必须手动 close() 关闭文件,容易忘记导致资源浪费。

方式2: with方式(推荐) 自动关闭,无需手动

with open('hm.jpg', mode='rb') as f_in:
    with open('hm[备份2].jpg', mode='wb') as f_out:
        # 读写文件
        data = f_in.read()
        f_out.write(data)

💡 推荐使用 with 方式:自动关闭文件,代码更安全、更简洁。

三、模块和包

1. 模块概述

模块:符合标识符命名规则的 .py 文件,就是 Python 模块。

标识符命名规则

规则说明
组成只能有字母、数字、下划线、汉字
注意不能以数字开头,不能是关键字,严格区分大小写,不建议用汉字

2. 自定义模块

自定义模块很简单:创建一个符合标识符命名规则的 .py 文件,里面定义函数或类即可

示例:创建一个名为 my_module1.py 的文件

3. 导入模块的两种方式

方式1: import 模块名(推荐)

import my_module1

my_module1.show()

方式2: from 模块名 import 功能

from my_module2 import show

show()

4. 导入模块的进阶用法

方式1: 给模块起别名

import my_module1 as m1

m1.show()

方式2: 给功能起别名

from my_module2 import show as show2

show2()

方式3: 导入模块中的所有功能(不推荐 ❌)

from my_module1 import *

show()

四、面向对象基础

1. 类的基本结构

class Student(object):
    # __init__():初始化对象的属性(重点)
    def __init__(self, name, age):
        # self 代表对象自己,谁调用当前方法,self 就是谁!
        self.name = name
        self.age = age

    # __str__():返回打印对象的内容(了解)
    def __str__(self):
        return f"姓名:{self.name},年龄:{self.age}"

    # __del__():对象删除时自动调用(了解)
    def __del__(self):
        print(f"{self.name}对象被删除了")

    # 自定义方法
    def study(self):
        print('好好学习,天天向上')


# 创建对象(自动调用 __init__())
zs = Student('张三', 18)
ls = Student('李四', 28)

# 打印对象(自动调用 __str__())
print(zs)  # 姓名:张三,年龄:18
print(ls)  # 姓名:李四,年龄:28

# 调用属性和方法
print(zs.name)
zs.study()
print(ls.name)
ls.study()

# 程序结束时,GC 垃圾回收器自动删除对象,调用 __del__()

2. 三大方法对比

方法触发时机作用掌握程度
__init__()创建对象时自动调用初始化对象的属性⭐⭐⭐⭐⭐ 重点
__str__()print(对象) 时调用返回对象的字符串描述⭐⭐⭐ 了解
__del__()对象被删除时自动调用释放资源、清理工作⭐⭐ 了解

3. 继承

继承:子类可以继承父类的属性和方法,实现代码复用。

3.1 单继承
# 父类(基类)
class Animal(object):
    def __init__(self, name):
        self.name = name

    def jiao(self):
        print(f'{self.name}会叫')


# 子类(派生类),继承 Animal
class Dog(Animal):
    # 重写父类方法,加入自己特有操作
    def jiao(self):
        print(f'{self.name}会汪汪叫')


class Cat(Animal):
    def jiao(self):
        print(f'{self.name}会喵喵叫')


# 创建对象
a = Animal("动物")
d = Dog('旺财狗')
c = Cat('招财猫')

a.jiao()  # 动物会叫
d.jiao()  # 旺财狗会汪汪叫
c.jiao()  # 招财猫会喵喵叫

# 查看继承关系(调用方法顺序)
print(Dog.mro())
print(Cat.mro())
3.2 多继承
class Father(object):
    def skill(self):
        print('生活中各种技能')


class HM(object):
    def skill(self):
        print('AI大模型的技能')


# 多继承:继承多个父类
class Student(Father, HM):
    def skill(self):
        # 调用父类的同名方法
        Father.skill(self)
        HM.skill(self)


s = Student()
s.skill()  # 如果两个父类方法重名,优先使用第一个父类的

# 查看方法查找顺序(深度优先,从左到右)
print(Student.mro())
print(Student.__mro__)

多继承方法查找顺序Student → Father → HM → object

3.3 继承总结
概念说明
单继承一个子类继承一个父类
多继承一个子类继承多个父类
重写子类重新定义父类的方法
mro()查看方法的调用顺序

4. 多态

多态:同一个方法在不同对象上有不同的表现形式。

class Animal(object):
    def __init__(self, name):
        self.name = name

    def jiao(self):
        print(f'{self.name}会叫')


class Dog():
    def __init__(self, name):
        self.name = name

    def jiao(self):
        print(f'{self.name}会汪汪叫')


class Cat():
    def __init__(self, name):
        self.name = name

    def jiao(self):
        print(f'{self.name}会喵喵叫')


# 公共的 API,传入动物类型对象,调用叫方法
def animal_jiao(animal):  # Python 是动态类型,不限制参数类型
    animal.jiao()


# 创建对象,传入 animal_jiao 方法中
d = Dog('旺财狗')
c = Cat('招财猫')
animal_jiao(d)  # 旺财狗会汪汪叫
animal_jiao(c)  # 招财猫会喵喵叫

💡 多态的好处:同一个函数 animal_jiao() 可以处理不同类型的对象,只要它们都有 jiao() 方法。

5. Python 动态类型

# 动态类型:变量可以随时改变类型
a = 10     # 此处 a 是整数类型
print(a)
a = "abc"  # 此处 a 变成字符串类型
print(a)

💡 静态类型 vs 动态类型

  • 静态类型(如 Java):变量类型一旦确定不能改变,编译时检查
  • 动态类型(如 Python):变量类型可以随时改变,运行时确定

6. 总结对比

概念说明
对一类事物的抽象描述(图纸)
对象根据类创建的具体实例(产品)
self代表当前对象本身
封装将数据和方法封装在类中
继承子类继承父类的属性和方法
重写子类重新定义父类的方法
多态同一个方法在不同对象上有不同表现