第一部分:基础知识

一、注释(Comments)

  • 单行注释

  • 用”#”开头,后面是注释内容;注释不会被python执行,仅用于说明代码逻辑。

  • print(“Hello”) # 这也是注释

  • 多行注释

  • 使用三个引号(’’’ 或 “””),更常用作文档说明(Docstring)
    “””
    这是多行注释(或文档字符串)
    适合用于函数、类说明
    “””

二、变量(Variables)

  • 变量命名规则

  • 只能包含字母、数字和下划线,不能以数字开头;不能是 Python 的关键字(如 if, class, def 等)
  • 命名方式:

  • snake_case(蛇形命名法),所有字母小写,单词间用下划线连接【常用于变量名&函数名】。
  • camelCase(小驼峰命名法),第一个单词首字母小写,后续单词首字母大写【Python中不常使用】。
  • PascalCase(大驼峰命名法),每个单词首字母都大写,不使用下划线【常用于类名】。
  • UPPER_CASE(全大写加下划线),所有字母大写,单词间用下划线分隔【常用于变量名】。

三、基本数据类型(Data Types)

  • int(整数)

  • float(浮点数)

  • complex(复数)

  • 布尔类型 bool()

  • 只有两个值:True 和 False,本质上是整数的子类:True == 1, False == 0。

  • 字符串类型 str()

一串字符,用 ‘ ‘ 或 “ “ 包围,字符串是不可变的,支持索引、切片、拼接、格式化等操作。

  • 字符串的基本操作:
    “””
    拼接:’a’ + ‘b’,得到 ‘ab’
    重复:’ha’ * 3,得到 ‘hahaha’
    获取长度:len(s),返回字符串长度
    成员测试:’a’ in ‘abc’, 返回 True
    比较: ‘abc’ == ‘abc’ , 返回 True(区分大小写)
    “””

  • 字符串索引与切片:Python 字符串是可索引的字符序列,支持正向、反向索引和切片。
    “””
    正向索引:s[0],’P’
    反向索引:s[-1],’n’
    切片:s[1:4],’yth’
    步长切片:s[::2],’Pto’
    逆序字符串:s[::-1],’nohtyP’
    “””

  • 字符串常用方法(不改变原字符串)

    • 大小写转换
      “””
      s.lower(): ‘Hello’.lower() → ‘hello’ 全部转小写
      s.upper(): ‘Hello’.upper() → ‘HELLO’ 全部转大写
      s.title(): ‘hello world’.title() → ‘Hello World’ 每个单词首字母大写
      s.capitalize(): ‘hello’.capitalize() → ‘Hello’ 首字母大写,其他小写
      s.swapcase(): ‘Hello’.swapcase() → ‘hELLO’ 大小写互换
      “””
    • 查找与判断类
      “””
      s.find(x): ‘hello’.find(‘l’) → 2 返回首次出现的索引,找不到返回 -1
      s.rfind(x): ‘hello’.rfind(‘l’) → 3 从右边开始查找
      s.index(x): ‘hello’.index(‘l’) → 2 与 find() 类似,找不到会报错
      s.startswith(x): ‘hello’.startswith(‘he’) → True 是否以指定字符串开头
      s.endswith(x): ‘hello’.endswith(‘lo’) → True 是否以指定字符串结尾
      x in s: ‘l’ in ‘hello’ → True 判断子串是否存在
      s.count(x): ‘hello’.count(‘l’) → 2 统计子串出现次数
      “””
    • 空白与字符清除类
      “””
      s.strip(): ‘ hi ‘.strip() → ‘hi’ 去除两边空格
      s.lstrip(): ‘ hi’.lstrip() → ‘hi’ 去除左侧空格
      s.rstrip(): ‘hi ‘.rstrip() → ‘hi’ 去除右侧空格
      s.strip(‘‘): ‘hi‘.strip(‘‘) → ‘hi’ 去除指定字符
      “””
    • 分割与连接类
      “””
      s.split(‘,’): ‘a,b,c’.split(‘,’) → [‘a’, ‘b’, ‘c’] 拆分为列表
      s.rsplit(‘,’, 1): ‘a,b,c’.rsplit(‘,’, 1) → [‘a,b’, ‘c’] 从右边最多分割一次
      ‘分隔符’.join(list): ‘,’.join([‘a’, ‘b’, ‘c’]) → ‘a,b,c’ 用逗号连接成字符串
      “””
    • 替换与格式类
      “””
      s.replace(a, b): ‘a-b-c’.replace(‘-‘, ‘_’) → ‘a_b_c’ 替换子串
      s.zfill(width): ‘42’.zfill(5) → ‘00042’ 前面补零到指定宽度
      s.center(width, fill): ‘hi’.center(6, ‘*’) → ‘hi‘ 居中对齐
      s.ljust(width, fill): ‘hi’.ljust(6, ‘-‘) → ‘hi—-‘ 左对齐
      s.rjust(width, fill): ‘hi’.rjust(6, ‘.’) → ‘….hi’ 右对齐
      “””
    • 字符串判断类(返回布尔值)
      “””
      s.isalpha(): ‘abc’.isalpha() → True 是否全是字母
      s.isdigit(): ‘123’.isdigit() → True 是否全是数字
      s.isalnum(): ‘abc123’.isalnum() → True 是否是字母或数字
      s.isspace(): ‘ ‘.isspace() → True 是否全是空白字符
      s.islower(): ‘abc’.islower() → True 是否全小写
      s.isupper(): ‘ABC’.isupper() → True 是否全大写
      “””
    • 格式化字符串(推荐使用 f-string)
      “””
      – f-string:print(f”My name is {name}, I’m {age:.2f} years old.”) # My name is Alice, I’m 20.25 years old. 注意保留小数写法
      – format 方法:print(“My name is {}, I’m {:.2f} years old.”.format(name, age ))
      – 百分号 % 格式化:print(“Name: %s, Age: %.2f “ % (“Tom”, 18))
      print(f”圆周率保留3位小数:{pi:.3f}”)
      print(f”数字加千位分隔符:{x:,.2f}”)
      print(f”正确率(百分比):{rate:.1%}”)
      “””
  • 序列类型(Sequence)

  • list(列表)

  • 可变、有序集合,用 [] 表示,可包含任意类型元素。fruits = [“apple”, “banana”, “cherry”]
    “””
    lst[x]:list([1,2])[0]→1 获取第x个元素
    lst[x:y]:list([1,2,3,4,5])[2:4]→[3,4] 获取第x到y个元素
    lst.append(x): [1, 2].append(3) → [1, 2, 3] 在末尾添加元素
    lst.insert(i, x): [1, 2].insert(1, 100) → [1, 100, 2] 在指定位置插入元素
    lst.extend(iter): [1].extend([2, 3]) → [1, 2, 3] 追加另一个序列
    lst.pop(): [1, 2].pop() → 2 → [1] 移除并返回最后一个元素
    lst.remove(x): [1, 2, 3].remove(2) → [1, 3] 移除指定值(不存在会报错)
    lst.index(x): [1, 2, 3].index(2) → 1 返回值首次出现的位置
    lst.count(x): [1, 2, 2, 3].count(2) → 2 统计元素出现次数
    lst.sort(): [3, 1, 2].sort() → [1, 2, 3] 原地升序排序
    sorted(lst): sorted([3, 1, 2]) → [1, 2, 3] 返回排序新列表
    lst.reverse(): [1, 2].reverse() → [2, 1] 原地反转列表
    lst.copy(): [1, 2].copy() → [1, 2] 返回浅复制
    lst.clear(): [1, 2].clear() → [] 清空列表
    “””

    tuple(元组)

  • 不可变的列表,用 () 表示,元组更安全,用于不希望被修改的数据。point = (3, 4)
    “””
    t.index(x): (1, 2, 3).index(2) → 1 返回值首次出现的位置
    t.count(x): (1, 2, 2, 3).count(2) → 2 统计元素出现次数
    解包: a, b = (1, 2) → a=1, b=2 多变量赋值
    “””

    range(范围)

  • 生成一系列连续整数(常用于循环)。
    “””
    for i in range(3): print(i) # 0, 1, 2
    “””

  • 集合类型(Set)

  • set(集合): 无序、唯一的元素集合,用 {} 或 set() 表示,支持集合运算(交集、并集、差集)
    “””
    s.add(x): {1, 2}.add(3) → {1, 2, 3} 添加元素
    s.remove(x): {1, 2}.remove(2) → {1} 删除指定元素(不存在报错)
    s.discard(x): {1, 2}.discard(3) → {1, 2} 删除指定元素(不存在不报错)
    s.pop(): {1, 2}.pop() → 1 随机移除并返回一个元素
    s.clear(): {1, 2}.clear() → {} 清空集合
    s.union(s2) 或 s s2: {1,2}.union({3}) → {1,2,3} 并集
    s.intersection(s2) 或 s & s2: {1,2}&{2,3} → {2} 交集
    s.difference(s2) 或 s - s2: {1,2,3}-{2} → {1,3} 差集
    set(iter): set([1,1,2]) → {1, 2} 从序列创建集合并去重
    “””

  • 映射类型(Mapping)

  • dict(字典),key-value 键值对集合,用 {} 表示,键唯一,值可以任意,person = {“name”: “Alice”, “age”: 25}
    “””
    d[k] = v: d[‘a’] = 1 → {‘a’:1} 添加或修改键值
    d.get(k, default): d.get(‘x’, 0) → 0 安全获取值,键不存在返回默认值
    d.pop(k): {‘a’:1}.pop(‘a’) → 1 删除并返回值
    d.keys(): {‘a’:1}.keys() → dict_keys([‘a’]) 获取所有键
    d.values(): {‘a’:1}.values() → dict_values([1]) 获取所有值
    d.items(): {‘a’:1}.items() → dict_items([(‘a’, 1)]) 获取键值对
    d.update(d2): d.update({‘b’:2}) → {‘a’:1, ‘b’:2} 批量更新键值
    d.clear(): {‘a’:1}.clear() → {} 清空字典
    遍历: for k, v in d.items(): 遍历键值对
    “””

  • 空值类型

  • 只有一个值:None,表示“什么都没有”,常用于函数没有返回值的情况。

  • type(x) # 返回数据类型

  • isinstance(x, int) # 判断是否是某种类型

四、类型转换(Type Conversion)

  • str → int / float ✅ 可行(内容需是数字)
  • int / float → str ✅ 可行
  • list ↔ tuple ✅ 可行
  • list / tuple → set ✅ 可行(自动去重)
  • 任意对象 → bool ✅ 可行
  • list → dict ⚠️需要键值对元素

五、运算符(Operators)

  • 算术运算符

  • 用于执行数学运算。
    “””
    加减乘除 / + - *
    取模 %
    幂 **
    整除 //
    “””

  • 比较运算符

  • 用于进行值之间的比较,结果是布尔值(True 或 False)

  • == != > < >= <=

  • 逻辑运算符

  • 用于布尔值逻辑判断,常用于 if 语句中;逻辑运算符优先级:and > or ,先计算and。

  • and:且(都为真为真)True and False False

  • or:或(一真为真) True or False True

  • not:非 not True False

  • 成员运算符

  • 用于判断某元素是否属于序列(如列表、字符串等)。

  • in:存在于,’a’ in ‘abc’,True

  • not in 不存在于,1 not in [2,3],True

  • 赋值运算符

  • 用于给变量赋值,支持复合运算。

  • = += -= *= /= %= **= //=

  • 身份运算符

  • 判断两个变量是否指向同一对象(内存地址)

  • is:是同一对象 a is b True / False

  • is not 不是同一对象 a is not b True / False
    “””
    a = [1, 2]
    b = a
    c = [1, 2]
    print(a is b) # True
    print(a is c) # False(虽然值一样但地址不同)
    “””

  • 位运算符

  • 对整数的二进制位进行操作,适用于底层或性能要求高的计算。
    “””
    & 与 5 & 3 0101 & 0011 → 0001(1)
    或 `5
    ^ 异或 5 ^ 3 0101 ^ 0011 → 0110(6)
    ~ 取反 ~5 ~0101 → 1010(-6)
    左移 << 2 << 1 0010 → 0100(4)
    右移 >> 4 >> 1 0100 → 0010(2)
    “””

六、条件语句(if / elif / else)

  • 条件语句

  • 语法结构
    “””
    if 条件1:
    代码块1 # 如果if条件成立,就执行对应的代码块1
    elif 条件2:
    代码块2 # 上面的if条件不满足时,继续判断该条件。
    else:
    代码块3 # 前面所有条件都不满足时执行。
    “””
  • 三元表达式

  • 语法结构
    “””
    结果1 if 条件 else 结果2,如果 条件 为 True,结果就是 结果1;否则是 结果2。
    “””
  • 特殊形式

  • if True: 意味着这个条件永远成立,对应的代码块 一定会被执行。

七、循环语句

  • for循环

  • 遍历可迭代对象(如列表、字符串、range),适合确定次数的循环。
    “””
    for 变量 in 可迭代对象:
    循环体
    “””
  • while循环

  • 只要条件为 True , 就会一直执行循环体。适合不确定次数的循环。
    “””
    while 条件:
    循环体
    “””
  • while True 无限循环 + 退出机制
    “””
    while True:
    cmd = input(“输入 exit 退出:”)
    if cmd == “exit”:
    break

“””

  • 终止条件

  • break:终止整个循环
  • continue:跳过本次循环,继续下一次
  • pass:不进行任何操作

八、模块与包(Modules & Packages)

  • 模块

模块是一个包含 Python 代码的文件,文件名就是模块名,扩展名为 .py

  • 导入模块:import module_name

  • 导入模块中的特定内容:from module_name import func_name, ClassName

  • 给模块或函数起别名:import module_name as alias

  • 包是含有多个模块的文件夹,文件夹里必须有一个特殊的 init.py 文件,包的作用是用来组织模块,使模块结构层次分明。包的名字对应文件夹名,模块对应文件。

    1
    2
    3
    4
    5
    6
    my_package/
    __init__.py
    module1.py
    sub_package/
    __init__.py
    module2.py
  • init.py 文件作用:标识当前文件夹是一个包,可以在这里写包的初始化代码;通过在 init.py 中定义 __all__,控制 from package import * 导入内容。

    1
    2
    my_package/__init__.py
    __all__ = ['module1'] # 只导入 module1,module2 不会被 * 导入
  • 导入包内模块:import my_package.module1

  • 导入子包中的模块:from my_package.sub_package import module2

  • 第三方包安装与管理

  • 使用 pip 安装第三方包:pip install 包名

  • 使用清华镜像源加速安装:pip3 install 包名 -i https://pypi.tuna.tsinghua.edu.cn/simple

  • 查看已安装包:pip list

  • 卸载包:pip uninstall 包名

第二部分:函数与作用域

一、函数

  • 定义: 函数是组织好的,可重复使用的,用来实现某一功能的代码段。函数需先定义再使用
    1
    2
    3
    4
    def 函数名(形式参数):
    函数功能
    # 调用
    函数名(实际参数)
  • 函数的参数

  • 位置参数(Positional Arguments):位置参数是最常见的参数类型,它们在函数调用时按照顺序传递给函数。传递的顺序和定义函数时的顺序必须一致。位置参数在调用时按照顺序传递。
    1
    2
    3
    4
    def greet(name, age):
    print(f"Hello, {name}. You are {age} years old.")

    greet("Tom", 25) # 输出:Hello, Tom. You are 25 years old.
  • 默认参数(Default Arguments):默认参数允许你在函数定义时为某些参数提供默认值。如果调用时没有传递这些参数,它们就会使用默认值。默认参数的值必须在函数定义时设定,如果使用了默认参数,它们必须放在位置参数的后面,即默认参数不能在位置参数之前定义。
    1
    2
    3
    4
    5
    def greet(name, age=30):
    print(f"Hello, {name}. You are {age} years old.")

    greet("Tom") # 输出:Hello, Tom. You are 30 years old.
    greet("Lucy", 25) # 输出:Hello, Lucy. You are 25 years old.
  • 可变位置参数(*args): args 用于接收不确定数量的位置参数,它将传入的所有位置参数收集到一个元组中。args 只能在函数的最后一个参数中使用;args 是一个元组,你可以像操作元组一样访问它。
    1
    2
    3
    4
    5
    def sum_numbers(*args):
    return sum(args)

    print(sum_numbers(1, 2, 3)) # 输出:6
    print(sum_numbers(5, 10, 15, 20)) # 输出:50
  • 可变关键字参数(**kwargs): kwargs 用于接收不确定数量的关键字参数,它将传入的所有关键字参数收集到一个字典中。kwargs 只能在函数的最后一个参数中使用,kwargs 是一个字典,可以像操作字典一样访问它。序列解包:在传递参数时,可以通过在实参前面加上一个*号表示传递给多个变量的形参。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def show_info(**kwargs):
    for key, value in kwargs.items():
    print(f"{key}: {value}")

    show_info(name="Tom", age=25, city="New York")
    # 输出:
    # name: Tom
    # age: 25
    # city: New York

二、作用域(Scope)

  • 定义:作用域是指在程序中,变量或函数名的有效范围,也就是程序能够访问这些变量或函数的区域。
  • 全局作用域(Global Scope)

  • 程序中的顶层,所有全局变量都可以在任何地方访问。global:用于在函数内部修改全局作用域中的变量。
  • 局部作用域(Local Scope)

  • 函数或代码块内部定义的变量,仅在函数或代码块内有效。

三、匿名函数:lambda函数

1
2
3
4
lambda 变量列表 : 表达式
lambda:关键字,表示这是一个匿名函数。
变量列表:可以有多个变量,类似于普通函数的参数。
表达式:必须是一个表达式(不能是多行语句),表达式的结果就是返回值。
  • 基本加法

  • lambda x, y: x + y
  • 与 sorted() 搭配进行自定义排序

  • sorted(data, key=lambda x: x[1])
  • 与 map() 搭配实现数据批量转换

  • map(lambda x: x**2, lst)
  • 与 filter() 搭配实现数据筛选

  • list(filter(lambda x: x >= 60, scores))

四、特殊函数

  • zip函数

  • zip() 是 Python 内置函数,它用于将多个可迭代对象(如列表、元组等)“压缩”在一起,返回一个元组的迭代器,其中每个元组包含来自各个可迭代对象对应位置的元素。如果输入的可迭代对象长度不同,zip 会以最短的可迭代对象为准,丢弃较长的可迭代对象中超出的元素。
    “””
    zip(iterable1, iterable2, …) # iterable1, iterable2, …:任意多个可迭代对象(如列表、元组等)。
    “””
  • 基本用法:zip([1, 2], [‘a’, ‘b’]) → [(1, ‘a’), (2, ‘b’)]
  • 长度不同情况:zip([1, 2, 3], [‘a’, ‘b’]) → [(1, ‘a’), (2, ‘b’)]
  • 多个可迭代对象:zip([1, 2], [‘a’, ‘b’], [‘x’, ‘y’]) → [(1, ‘a’, ‘x’), (2, ‘b’, ‘y’)]
  • 解压操作(Unzipping):zip(*[(1, ‘a’), (2, ‘b’)]) → [(1, 2), (‘a’, ‘b’)]
  • 与字典结合:dict(zip(keys, values)) → {‘name’: ‘Tom’, ‘age’: 25}

回调函数(callback function)

  • 将一个函数作为参数传递给另一个函数,并在合适的时机被调用的函数。
    1
    2
    3
    4
    5
    6
    7
    8
    def double(x):
    return x * 2

    def process_number(func, number):
    result = func(number)
    return result

    print(process_number(double, 5)) # 输出:10

递归函数(Recursive Function)

  • 指在函数内部调用自身的函数.
  • 递归函数的两个要点:递归终止条件(base case):告诉函数什么时候“别再自己调用自己”;递归调用(recursive call):函数内部自己调用自己。
    1
    2
    3
    4
    5
    6
    7
    def factorial(n):
    if n == 0:
    return 1 # 终止条件
    else:
    return n * factorial(n - 1) # 递归调用

    print(factorial(5)) # 输出:120

filter()函数

  • 从可迭代对象中 筛选出符合条件的元素,返回一个迭代器。
    “””
    filter(function, iterable)
    function:返回 True 或 False 的函数
    iterable:如列表、元组、字符串等
    “””
  • 示例 过滤掉空字符串:non_empty = list( filter(None, words) )

enumerate()函数

  • 为可迭代对象添加索引,常用于 for 循环中,同时获得索引和值。
  • enumerate(iterable): 添加索引 list(enumerate([‘a’,’b’])) [(0,’a’),(1,’b’)]

第三部分:异常处理(Exception Handling)

  • 异常是程序运行过程中出现的错误,会导致程序中断执行 ; 通过异常处理,程序可以捕获这些错误并做相应处理,避免程序崩溃。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    try:
    # 可能出错的代码块
    except SomeException:
    # 发生 SomeException 时执行的代码 (# 捕获指定异常,处理异常)
    except AnotherException as e:
    # 发生 AnotherException 时执行的代码,可以获取异常对象 e (# 捕获指定异常,处理异常)
    else:
    # 没有异常时执行的代码
    finally:
    # 无论是否发生异常,都会执行的代码块

常见异常类型【可自定义异常】

“””
ZeroDivisionError 除数为零错误
IndexError 索引超出范围
KeyError 字典中不存在的键
NameError 未声明/初始化对象(没有属性)
TypeError 类型错误
ValueError 值错误
FileNotFoundError 文件未找到
SyntaxError Python 语法错误对类型无效的操作TypeError
Exception 所有异常的基类,捕获所有异常
“””

第四部分:面向对象编程(OOP)

  • 定义:面向对象编程(Object-Oriented Programming,简称 OOP)是一种编程思想,它把现实世界中的事物抽象成“对象”,通过对象之间的相互协作来完成程序的功能。

  • 类就像一个模板,用来描述一类对象应该具备的属性和行为。比如,定义一个“猫”的类
    “””
    class Cat:
    pass
    “””

对象

  • 是根据类创建出来的具体实例。比如,创建了一个“猫”的对象,叫做 my_cat
    “””
    my_cat = Cat()
    “””

属性(变量)

  • 用于描述对象的状态,比如猫的颜色、年龄等。
  • 实例属性

  • 属于对象本身,每个对象独立拥有。
  • 类属性

  • 属于类,所有对象共享。

方法(函数)

  • 用于定义对象能做什么,比如叫、抓老鼠等。
    “””
    装饰器:无(默认);@classmethod;@staticmethod
    第一个参数:self(对象);cls(类);无
    访问实例属性:✅ 可以;❌ 不可以 ;❌ 不可以
    访问类属性:✅ 可以; ✅ 可以 ;❌ 不可以
    绑定方式:绑定到对象; 绑定到类 ;绑定到类
    常用场景:操作当前对象;操作类的状态、创建实例;工具类函数,逻辑属于类但不访问属性
    “””
  • 实例方法

  • 必须有 self 参数,表示当前实例。【处理“我这个对象”的事】
  • 第一个参数是 self,代表当前对象本身,通过对象调用(如 obj.instance_method());可以访问对象的属性(self.instance_attr),也可以访问类的属性(通过 self.class.class_attr),当你的方法需要访问或修改“这个对象”的数据时。
  • 类方法

  • 使用装饰器 @classmethod,第一个参数是 cls,表示类本身。【处理“这个类”的事】
  • 用 @classmethod 装饰,第一个参数是 cls,代表这个类本身;只能访问类属性(如 cls.class_attr),不能访问实例属性。当方法的操作与类相关,但不依赖于具体对象时使用。
  • 静态方法

  • 使用装饰器 @staticmethod,不需要 self 或 cls。【处理“和这个类有关,但谁都不依赖”的事】
  • 用 @staticmethod 装饰,没有 self 或 cls 参数,是一个普通函数,只是放在类的名字空间里,不能访问实例属性或类属性;当你的方法逻辑上属于类,但不需要用到类或对象的数据时。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    class MyClass:
    class_attr = 42

    def __init__(self, val):
    self.instance_attr = val

    def instance_method(self):
    print(f"Instance method called, instance_attr = {self.instance_attr}")

    @classmethod
    def class_method(cls):
    print(f"Class method called, class_attr = {cls.class_attr}")

    @staticmethod
    def static_method():
    print("Static method called")

    obj = MyClass(10)
    obj.instance_method()
    MyClass.class_method()
    MyClass.static_method()

    Instance method called, instance_attr = 10
    Class method called, class_attr = 42
    Static method called

继承(Inheritance)

  • 继承是指子类自动获得父类的属性和方法,以实现代码的复用与扩展。
  • 如果子类重写了函数【即子类和父类拥有相同的函数名函数】,那么调用的是子类的函数。
  • 子类没有定义结构函数,那么创建对象的传参是传到父类的结构函数处;子类可以继承父类的结构函数,且增加参数;若不是继承,子类的 init() 会覆盖父类的构造函数,而不会自动调用父类的 init()。
  • 参数传递

  • 先写父类的参数,再写子类自己的参数
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class Animal:
    def __init__(self, name, age):
    self.name = name
    self.age = age

    class Dog(Animal):
    def __init__(self, name, age, breed):
    super().__init__(name, age) # 👈 先传父类需要的参数
    self.breed = breed # 👈 再初始化子类自己的参数
    """
    ### 示例
    """
    class Animal:
    def __init__(self, name):
    self.name = name

    def speak(self):
    print(f"{self.name} makes a sound")

    def sleep(self):
    print(f"{self.name} is sleeping")

    # 子类重写 speak,但没有重写 __init__ 和 sleep
    class Dog(Animal):
    def speak(self):
    print(f"{self.name} says woof!")

    dog = Dog("Buddy") # 这是传给了 Animal 的 __init__(),因为子类Dog没有重写 __init__结构函数
    dog.speak() # 自己的 speak
    dog.sleep() # sleep 来自 Animal

    Buddy says woof!
    Buddy is sleeping

封装(Encapsulation)

  • 封装 = 隐藏内部实现细节 + 对外提供统一接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Employee:
def __init__(self, name, salary, ssn):
self.name = name # 公有属性
self._salary = salary # 受保护属性(约定不要直接访问)
self.__ssn = ssn # 私有属性(不能直接访问)

def display_info(self):
print(f"Name: {self.name}, Salary: {self._salary}, SSN: {self.__ssn}")

def get_ssn(self):
return self.__ssn # 提供安全访问私有属性的接口

def set_salary(self, new_salary):
if new_salary > 0:
self._salary = new_salary
else:
print("Invalid salary.")

emp = Employee("Alice", 8000, "123-45-6789")

# ✅ 访问公有属性
print(emp.name) # 输出: Alice

# ⚠️ 访问受保护属性(可以访问,但不推荐)
print(emp._salary) # 输出: 8000

# ❌ 尝试访问私有属性,失败
# print(emp.__ssn) # AttributeError: 'Employee' object has no attribute '__ssn'

# ✅ 正确访问私有属性
print(emp.get_ssn()) # 输出: 123-45-6789

# ✅ 修改受保护属性(通过方法)
emp.set_salary(9000)
print(emp._salary) # 输出: 9000

# 🚨 强行访问私有属性(通过名称重整)
print(emp._Employee__ssn) # 输出: 123-45-6789(不推荐)
  • Public公有属性

  • 无前缀; ✅是 ;所有用户都可以访问的数据/方法
  • Protected受保护属性

  • _ 前缀 ;⚠️ 是,但不建议;类内或子类使用,外部应避免访问
  • Private私有属性

  • __ 前缀;❌ 否(除非用重命名方式);完全内部使用,保护敏感数据

    定义:封装的本质,就是“控制访问”,防止外部代码随意篡改对象的内部状态,只允许它通过设定好的方式(方法)来操作属性。

    1
    2
    3
    4
    银行金库:__balance
    外部不能直接进去(不能 acc.__balance = -1000)
    想存钱/取钱,只能走柜台操作(deposit() / withdraw())
    柜台操作是你提前设定好的逻辑,比如:不能取负数,不能超过余额等

多态(Polymorphism)

  • 多态是“面向对象”里的概念,强调的是“同一个方法名在不同类的对象上,表现出不同的行为”。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    class Animal:
    def speak(self):
    print("Animal makes a sound")

    class Dog(Animal):
    def speak(self):
    print("Dog says woof!")

    class Cat(Animal):
    def speak(self):
    print("Cat says meow!")

    # 多态性体现在这里:
    def make_animal_speak(animal):
    animal.speak()

    # 调用时表现不同
    make_animal_speak(Dog()) # 输出: Dog says woof!
    make_animal_speak(Cat()) # 输出: Cat says meow!