面向对象(二)

类的继承

  • 说明

    类继承是面向对象编程的核心概念之一,它允许我们基于已有的类创建新类,从而实现代码重用和层次化设计。下面详细介绍 Python 中的类继承机制。

  • 继承的特点

    • 代码重用:子类自动获得父类的所有功能
    • 扩展性:子类可以添加新的属性和方法
    • 多态性:子类可以重写父类的方法,实现不同的行为
  • 基本继承(单继承)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class ParentClass:
    def parent_method(self):
    print("这是父类方法")

    class ChildClass(ParentClass): # 继承ParentClass
    def child_method(self):
    print("这是子类方法")

    child = ChildClass()
    child.parent_method() # 调用继承的父类方法
    child.child_method() # 调用子类自己的方法
  • 方法重写(Override)

    子类可以重写父类的方法以提供特定实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Animal:
    def make_sound(self):
    print("动物发出声音")

    class Dog(Animal):
    def make_sound(self): # 重写父类方法
    print("汪汪汪!")

    dog = Dog()
    dog.make_sound() # 输出: 汪汪汪!
  • 调用父类方法

    可以使用 super() 函数调用父类的方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class Animal:
    def __init__(self, name):
    self.name = name

    class Dog(Animal):
    def __init__(self, name, breed):
    super().__init__(name) # 调用父类的__init__
    self.breed = breed

    dog = Dog("旺财", "金毛")
    print(dog.name) # 旺财
    print(dog.breed) # 金毛
  • 多继承

    Python 支持多继承,即一个类可以继承多个父类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    class Father:
    def skills(self):
    print("编程、修理")

    class Mother:
    def skills(self):
    print("烹饪、艺术")

    class Child(Father, Mother):
    def skills(self):
    Father.skills(self) # 调用Father的skills方法
    Mother.skills(self) # 调用Mother的skills方法
    print("运动")

    child = Child()
    child.skills()

    方法解析顺序(MRO):多继承时,Python 使用 C3 线性化算法确定方法调用顺序

    1
    print(Child.__mro__)  # 查看方法解析顺序
  • 抽象基类

    使用 abc 模块可以定义抽象基类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    from abc import ABC, abstractmethod

    class Shape(ABC):
    @abstractmethod
    def area(self):
    pass

    class Circle(Shape):
    def __init__(self, radius):
    self.radius = radius

    def area(self): # 必须实现抽象方法
    return 3.14 * self.radius ** 2

    # shape = Shape() # 会报错,不能实例化抽象类
    circle = Circle(5)
    print(circle.area())
  • 继承的实用技巧

    检查继承关系:使用 isinstance()issubclass()

    1
    2
    issubclass(Child, Parent)  # 检查继承关系
    isinstance(obj, Class) # 检查对象是否是类的实例
  • 混入类(Mixin):一种多继承的特殊用法,用于添加功能而非作为主要类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class JsonMixin:
    def to_json(self):
    import json
    return json.dumps(self.__dict__)

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

    class JsonPerson(Person, JsonMixin):
    pass

    p = JsonPerson("张三")
    print(p.to_json()) # 输出: {"name": "张三"}

访问权限

  • 说明

    在 Python 中,类的成员(属性和方法)的访问权限是通过命名约定来实现的,而不是像 Java 或 C++ 那样有严格的访问修饰符(如 public、private、protected)。Python 采用的是"约定优于强制"的原则。

  • 公开成员 (Public)

    • 默认情况下,所有类成员都是公开的
    • 可以从类的外部直接访问
    • 命名方式:直接使用名称,不加任何前缀
    • 示例
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      class MyClass:
      def __init__(self):
      self.public_attr = "I'm public"

      def public_method(self):
      return "Public method"

      obj = MyClass()
      print(obj.public_attr) # 可以直接访问
      print(obj.public_method()) # 可以直接调用
  • 受保护成员 (Protected)

    • 约定上应该只在类及其子类中访问,但实际上外部仍可访问
    • 命名方式:以单下划线 _ 开头
    • 这是一种提示,告诉其他程序员"这是内部实现,不建议直接访问"
    • 示例
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      class MyClass:
      def __init__(self):
      self._protected_attr = "I'm protected"

      def _protected_method(self):
      return "Protected method"

      obj = MyClass()
      print(obj._protected_attr) # 仍然可以访问,但不建议
      print(obj._protected_method()) # 仍然可以调用,但不建议
  • 私有成员 (Private)

    • 约定上只能在类内部访问,外部不能直接访问
    • 命名方式:以双下划线 __ 开头(但不以双下划线结尾)
    • Python 会对这样的名称进行名称修饰 (name mangling),使其难以直接访问
    • 示例
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      class MyClass:
      def __init__(self):
      self.__private_attr = "I'm private"

      def __private_method(self):
      return "Private method"

      def access_private(self):
      print(self.__private_attr) # 类内部可以访问
      print(self.__private_method()) # 类内部可以调用

      obj = MyClass()
      # print(obj.__private_attr) # 直接访问会报错
      # print(obj.__private_method()) # 直接调用会报错
      obj.access_private() # 可以通过公有方法间接访问

      # 实际上可以通过名称修饰后的名称访问(但不推荐)
      print(obj._MyClass__private_attr)
      print(obj._MyClass__private_method())
  • 特殊成员

    • 以双下划线开头和结尾的成员是 Python 的特殊方法
    • 例如 __init__, __str__, __len__
    • 这些方法可以被外部调用,但通常不直接调用而是通过特定操作触发
    • 示例
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      class MyClass:
      def __init__(self):
      self.value = 42

      def __str__(self):
      return f"MyClass with value {self.value}"

      obj = MyClass()
      print(obj) # 自动调用 __str__
      print(obj.__str__()) # 也可以直接调用(但不常见)
  • 总结

    访问权限 命名约定 实际可访问性 使用建议
    公开 无前缀 任何地方 无限制
    受保护 _ 开头 任何地方 仅在类和子类中使用
    私有 __ 开头 类内部(可通过名称修饰访问) 仅在类内部使用
    特殊 __ 开头和结尾 任何地方 按需实现特殊方法

类属性

  • 说明

    • 定义时,写在类中,但是方法外的属性,通常放在类的开头位置
    • 类属性是 Python 面向对象编程中的一个重要概念,它是属于类本身的属性,而不是属于类的实例的属性。
  • 基本概念

    • 定义在类内部,但在任何方法之外
    • 属于类本身,而不是类的实例
    • 所有实例共享同一个类属性
    • 可以通过类名或实例名访问
  • 定义类属性

    1
    2
    3
    4
    5
    class MyClass:
    class_attribute = "我是类属性" # 这是一个类属性

    def __init__(self):
    self.instance_attribute = "我是实例属性" # 这是一个实例属性
  • 访问类属性

    1. 通过类名直接访问:

      1
      print(MyClass.class_attribute)  # 输出: 我是类属性
    2. 通过实例访问:

      1
      2
      obj = MyClass()
      print(obj.class_attribute) # 输出: 我是类属性
  • 类属性 vs 实例属性

    • 类属性
      • 属于类本身
      • 所有实例共享
      • 修改会影响所有实例
    • 实例属性
      • 属于特定实例
      • 每个实例有自己的副本
      • 修改只影响当前实例
  • 修改类属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class Dog:
    species = "Canis familiaris" # 类属性

    def __init__(self, name):
    self.name = name # 实例属性

    # 修改类属性
    Dog.species = "Canis lupus" # 会影响所有实例

    dog1 = Dog("Buddy")
    dog2 = Dog("Max")

    print(dog1.species) # 输出: Canis lupus
    print(dog2.species) # 输出: Canis lupus
  • 类属性的常见用途

    1. 存储类级别的常量

      1
      2
      3
      4
      5
      6
      7
      8
      class Circle:
      PI = 3.14159 # 类属性作为常量

      def __init__(self, radius):
      self.radius = radius

      def area(self):
      return self.PI * self.radius ** 2
    2. 跟踪类级别的信息

      1
      2
      3
      4
      5
      6
      class Person:
      count = 0 # 跟踪创建的实例数量

      def __init__(self, name):
      self.name = name
      Person.count += 1
    3. 提供默认值

      1
      2
      3
      4
      5
      class Car:
      wheels = 4 # 所有汽车的默认轮子数量

      def __init__(self, model):
      self.model = model
  • 注意事项

    如果通过实例修改类属性,实际上会创建一个同名的实例属性,而不会修改类属性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Test:
    class_attr = 10

    t1 = Test()
    t2 = Test()

    t1.class_attr = 20 # 这会创建一个实例属性,不会修改类属性

    print(t1.class_attr) # 输出: 20 (实例属性)
    print(t2.class_attr) # 输出: 10 (类属性)
    print(Test.class_attr) # 输出: 10 (类属性未改变)
  • 示例

    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
    class Person:
    # 定义类属性
    nation = '中国'

    def __init__(self, name):
    self.name = name
    self.nation = 'china'


    # 通过类名访问类属性
    print(Person.nation)

    # 通过对象也可以访问类属性,但是不建议
    # 当对象有同名的成员属性时,使用的就是成员属性
    p = Person('xiaoming')
    print(p.nation)

    # 也可以动态添加
    Person.hello = 'hello'
    print(Person.hello)

    # 特殊的类属性
    # 表示类名字符串
    print(Person.__name__)

    # 表示父类构成的元组
    print(Person.__bases__)

    # 存储类相关的信息
    print(Person.__dict__)

类方法

  • 说明

    • 定义时使用装饰器:classmethod
    • 类方法是绑定到类而不是实例的方法,它接收类作为第一个隐式参数(通常命名为 cls),而不是实例(self)。
  • 特点

    • 使用 @classmethod 装饰器定义
    • 第一个参数是类本身(通常命名为 cls
    • 可以访问和修改类状态
    • 可以被类和实例调用
  • 使用场景

    • 当需要操作类属性而不是实例属性时
    • 实现替代构造函数(提供多种实例化方式)
    • 在继承时,确保子类使用时能获取正确的类
  • 示例1:语法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    class MyClass:
    class_attr = "类属性"

    @classmethod
    def class_method(cls):
    print(f"这是一个类方法,可以访问{cls.class_attr}")
    return cls() # 可以返回类的新实例

    # 通过类调用
    MyClass.class_method()

    # 通过实例调用
    obj = MyClass()
    obj.class_method()
  • 示例2

    设计一个数字类,有两个属性,能够进行加减乘除运算,要求:计算两个数的平方和

    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 Number:
    def __init__(self, num1, num2):
    self.num1 = num1
    self.num2 = num2

    def add(self):
    return self.num1 + self.num2

    def sub(self):
    return self.num1 - self.num2

    def mul(self):
    return self.num1 * self.num2

    def div(self):
    if self.num2 == 0:
    return 0
    return self.num1 / self.num2

    @classmethod
    def pingfanghe(cls, num1, num2):
    # 第一个数
    n1 = Number(num1, num1)
    # 求平方
    n12 = n1.mul()

    # 第二个数
    n2 = Number(num2, num2)
    # 求平方
    n22 = n2.mul()

    # 第三个数
    n3 = Number(n12, n22)
    # 求和
    return n3.add()


    print(Number.pingfanghe(3, 4))

静态方法

  • 说明

    • 使用装饰器:staticmethod进行修饰
    • 静态方法不接收隐式的第一个参数(既不是 self 也不是 cls),它就像定义在类中的普通函数。
  • 特点

    • 使用 @staticmethod 装饰器定义
    • 不接受自动传入的 selfcls 参数
    • 不能访问类或实例的状态
    • 可以被类和实例调用
  • 使用场景

    • 当方法与类相关但不依赖类或实例状态时
    • 将函数组织到类中(逻辑上属于该类)
    • 实现与类相关的工具函数
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class MathUtils:
    @staticmethod
    def add(x, y):
    return x + y

    @staticmethod
    def multiply(x, y):
    return x * y

    # 通过类调用
    print(MathUtils.add(2, 3)) # 输出: 5

    # 通过实例调用
    calc = MathUtils()
    print(calc.multiply(4, 5)) # 输出: 20
  • 主要区别

    特性 实例方法 类方法 静态方法
    装饰器 @classmethod @staticmethod
    第一个参数 self (实例) cls (类)
    访问实例属性 可以 不可以 不可以
    访问类属性 通过self.class 可以 不可以
    调用方式 必须通过实例 类或实例 类或实例

多态特性

  • 说明

    多态(Polymorphism)是面向对象编程的三大基本特征之一(另外两个是封装和继承),指的是同一操作作用于不同类的实例时,能产生不同的执行结果。

  • 多态的核心概念

    • 同一接口,不同实现:不同的类可以有相同名称的方法,但具体实现不同
    • 运行时确定:在运行时根据对象的实际类型决定调用哪个方法
    • 鸭子类型(Duck Typing):Python特有的多态实现方式,“如果它走起来像鸭子,叫起来像鸭子,那么它就是鸭子”
  • 实现多态的方式

    1. 继承与方法重写

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      class Animal:
      def speak(self):
      pass

      class Dog(Animal):
      def speak(self):
      return "汪汪!"

      class Cat(Animal):
      def speak(self):
      return "喵喵!"

      def animal_sound(animal):
      print(animal.speak())

      dog = Dog()
      cat = Cat()

      animal_sound(dog) # 输出: 汪汪!
      animal_sound(cat) # 输出: 喵喵!
    2. 鸭子类型

      Python 更推崇"鸭子类型",不强制要求继承关系

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      class Dog:
      def speak(self):
      return "汪汪!"

      class Cat:
      def speak(self):
      return "喵喵!"

      class Car:
      def speak(self):
      return "滴滴!"

      def make_sound(obj):
      print(obj.speak())

      make_sound(Dog()) # 汪汪!
      make_sound(Cat()) # 喵喵!
      make_sound(Car()) # 滴滴!
    3. 运算符重载

      Python 通过特殊方法实现运算符多态

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      class Vector:
      def __init__(self, x, y):
      self.x = x
      self.y = y

      def __add__(self, other):
      return Vector(self.x + other.x, self.y + other.y)

      def __str__(self):
      return f"Vector({self.x}, {self.y})"

      v1 = Vector(2, 3)
      v2 = Vector(4, 5)
      print(v1 + v2) # 输出: Vector(6, 8)
  • 多态的优点

    • 提高代码灵活性:可以编写更通用的代码
    • 增强可扩展性:添加新类时不需要修改现有代码
    • 接口统一:不同对象可以使用相同的方式进行操作
    • 简化代码:减少条件判断语句的使用

属性方法

  • 说明

    • 使用装饰器:property 进行修饰
    • 属性方法(property method)是 Python 中一种强大的特性,它允许你将方法作为属性来访问,同时可以在访问时执行额外的逻辑。这是 Python 实现 getter 和 setter 的一种优雅方式。
  • 基本概念

    属性方法使用 @property 装饰器来创建,通常与 @<property_name>.setter@<property_name>.deleter 装饰器配合使用。

    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
    class MyClass:
    def __init__(self, value):
    self._value = value # 注意这里使用下划线前缀表示这是一个"受保护"的属性

    @property
    def value(self):
    """Getter 方法"""
    print("Getting value")
    return self._value

    @value.setter
    def value(self, new_value):
    """Setter 方法"""
    print("Setting value")
    self._value = new_value

    @value.deleter
    def value(self):
    """Deleter 方法"""
    print("Deleting value")
    del self._value


    obj = MyClass(10)

    # 访问属性(调用getter)
    print(obj.value) # 输出: Getting value \n 10

    # 设置属性(调用setter)
    obj.value = 20 # 输出: Setting value

    # 删除属性(调用deleter)
    del obj.value # 输出: Deleting value
  • 优点

    • 封装性:可以在访问属性时添加验证或其他逻辑
    • 向后兼容:可以将普通属性转换为属性方法而不影响现有代码
    • 计算属性:可以创建基于其他属性的动态计算属性
  • 示例

    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
    class Circle:
    def __init__(self, radius):
    self.radius = radius

    @property
    def radius(self):
    return self._radius

    @radius.setter
    def radius(self, value):
    if value <= 0:
    raise ValueError("Radius must be positive")
    self._radius = value

    @property
    def diameter(self):
    return 2 * self._radius

    @property
    def area(self):
    return 3.14159 * (self._radius ** 2)


    c = Circle(5)
    print(c.radius) # 5
    print(c.diameter) # 10
    print(c.area) # 78.53975

    c.radius = 10
    print(c.diameter) # 20

    try:
    c.radius = -1 # 抛出 ValueError
    except ValueError as e:
    print(e)
  • 注意事项

    • 属性方法不能接受除 self 之外的参数
    • 属性方法通常用于封装内部表示,提供更友好的接口
    • 过度使用属性方法可能会使代码变得复杂

函数判断

  • 问题

    如何判断一个对象是否可以像函数一样调用(即可调用对象)?

  1. 使用 callable() 函数

    最简单的方法是使用内置的 callable() 函数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def my_func():
    pass

    class MyClass:
    def __call__(self):
    pass

    print(callable(my_func)) # 输出: True
    print(callable(MyClass())) # 输出: True (因为实现了 __call__)
    print(callable("hello")) # 输出: False
  2. 检查 __call__ 方法

    你也可以检查对象是否有 __call__ 方法:

    1
    2
    3
    4
    5
    def is_callable(obj):
    return hasattr(obj, '__call__')

    print(is_callable(lambda x: x+1)) # 输出: True
    print(is_callable([1,2,3])) # 输出: False
  3. 使用 collections.abc.Callable (Python 3.3+)

    对于更正式的类型检查,可以使用 collections.abc 模块:

    1
    2
    3
    4
    5
    6
    7
    from collections.abc import Callable

    def my_func():
    return 42

    print(isinstance(my_func, Callable)) # 输出: True
    print(isinstance(123, Callable)) # 输出: False
  • 注意事项

    1. callable() 在 Python 3.x 中总是可用,但在 Python 2 中曾被移除过一段时间
    2. 类本身也是可调用的(调用类会创建实例)
    3. 实现了 __call__ 方法的类的实例是可调用的
    4. 方法(绑定或未绑定的)也是可调用的
  • 实际应用示例

    1
    2
    3
    4
    5
    6
    7
    8
    def safe_call(func, *args, **kwargs):
    if not callable(func):
    raise TypeError(f"对象 {func} 不可调用")
    return func(*args, **kwargs)

    # 使用示例
    safe_call(print, "Hello, World!") # 正常调用
    safe_call("not a function") # 抛出 TypeError
  • inspect.isfunction()

    • inspect.isfunction() 不能 完全替代 callable() 或其它方法来判断对象是否可调用,因为它的用途更特定,只检测标准函数(function)类型,而 Python 中可调用对象的范围更广。
    • inspect.isfunction() 的局限性
      1. 仅识别纯函数
        它只能识别用 def 定义的函数或 lambda 创建的函数,但会忽略其他可调用对象:

        1
        2
        3
        4
        5
        6
        7
        from inspect import isfunction

        def my_func(): pass
        print(isfunction(my_func)) # True ✅

        lambda_func = lambda x: x
        print(isfunction(lambda_func)) # True ✅
      2. 漏判其他可调用对象
        以下常见可调用对象会被误判为 False

        1
        2
        3
        4
        5
        6
        7
        8
        9
        class CallableClass:
        def __call__(self): pass

        obj = CallableClass()
        print(isfunction(obj)) # False ❌(实际可调用)

        print(isfunction(print)) # False ❌(内置函数)
        print(isfunction(str.upper)) # False ❌(方法)
        print(isfunction(int)) # False ❌(类是可调用的)
  • 如何选择正确的判断方法?

    方法 覆盖范围 典型用例
    callable(obj) 最广泛(函数、类、方法、实现了 __call__ 的对象等) 通用场景,推荐优先使用
    inspect.isfunction(obj) 仅纯函数(def/lambda 需要严格限定为函数对象时
    isinstance(obj, Callable) 类似 callable(),但更符合类型注解规范 类型检查或静态分析

数据持久化存储

  • 概述

    Python 提供了多种数据持久化存储的方式,可以将内存中的数据保存到磁盘中,以便后续使用。

  1. pickle 模块

    • 简介

      pickle 是 Python 标准库中最常用的序列化模块,可以将几乎任何 Python 对象转换为字节流(序列化),也可以将字节流还原为 Python 对象(反序列化)。

    • 基本用法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      import pickle

      # 序列化对象到文件
      data = {'name': 'Alice', 'age': 25, 'scores': [88, 92, 95]}
      with open('data.pkl', 'wb') as f:
      pickle.dump(data, f)

      # 从文件反序列化
      with open('data.pkl', 'rb') as f:
      loaded_data = pickle.load(f)
      print(loaded_data) # {'name': 'Alice', 'age': 25, 'scores': [88, 92, 95]}
    • 优缺点

      • 优点:可以序列化几乎所有 Python 对象,使用简单
      • 缺点:不安全(可能执行任意代码),不同 Python 版本间可能不兼容
  2. json 模块

    • 简介

      对于基本的数据结构(字典、列表、字符串、数字等),可以使用 JSON 格式进行序列化。

    • 基本用法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      import json

      data = {'name': 'Bob', 'age': 30, 'married': True}

      # 写入 JSON 文件
      with open('data.json', 'w') as f:
      json.dump(data, f)

      # 读取 JSON 文件
      with open('data.json', 'r') as f:
      loaded_data = json.load(f)
      print(loaded_data) # {'name': 'Bob', 'age': 30, 'married': True}
    • 优缺点

      • 优点:跨语言兼容,人类可读,安全
      • 缺点:只能处理基本数据类型,无法直接序列化自定义类实例
  3. shelve 模块

    • 简介

      shelve 提供了一个简单的键值存储,类似于字典,但数据持久化到磁盘。

    • 基本用法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      import shelve

      # 写入数据
      with shelve.open('mydata') as db:
      db['name'] = 'Charlie'
      db['info'] = {'age': 35, 'job': 'developer'}

      # 读取数据
      with shelve.open('mydata') as db:
      print(db['name']) # Charlie
      print(db['info']) # {'age': 35, 'job': 'developer'}
  4. SQLite 数据库

    • 简介

      Python 内置了 SQLite 支持,适合更结构化的数据存储。

    • 基本用法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      import sqlite3

      # 创建数据库和表
      conn = sqlite3.connect('example.db')
      c = conn.cursor()
      c.execute('''CREATE TABLE IF NOT EXISTS users
      (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)''')

      # 插入数据
      c.execute("INSERT INTO users VALUES (1, 'Diana', 28)")
      conn.commit()

      # 查询数据
      for row in c.execute('SELECT * FROM users'):
      print(row) # (1, 'Diana', 28)

      conn.close()
  5. HDF5 (h5py)

    • 简介

      对于科学计算中的大型数值数据,HDF5 是高效的选择。

    • 基本用法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      import h5py
      import numpy as np

      # 创建 HDF5 文件并写入数据
      data = np.random.rand(100, 100)
      with h5py.File('data.h5', 'w') as f:
      f.create_dataset('dataset', data=data)

      # 读取数据
      with h5py.File('data.h5', 'r') as f:
      loaded_data = f['dataset'][:]
  • 选择建议

    • 简单 Python 对象:pickle,注意:使用 pickle 时不要反序列化不受信任的数据,这可能导致安全问题。
    • 跨语言/人类可读:json
    • 键值存储:shelve
    • 结构化数据:sqlite3
    • 大型数值数据:h5py
本文结束 感谢您的阅读
正在加载今日诗词....