《Quark 的大纲:Python 类实例》

概述、历史时间线、问题与解决方案

Python 类实例概述

什么是 Python 类实例?

你使用类来描述某个事物应该如何工作。当你调用这个类时,你创建了一个类实例。Python 类实例是由类生成的对象。它拥有自己存储值和执行操作的空间。

当你写 Dog() 时,你调用了 Dog 类。Python 执行 __init__ 方法来初始化这个对象。结果是一个新的类实例。你可以将其存储在一个名称下,例如 my_dog。你可以给它赋值,比如 my_dog.name = "Spot"

Python 允许你通过调用类来创建新对象。

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

my_dog = Dog("Spot")
print(my_dog.name)
# 输出: Spot

Python 如何在类实例中存储属性?

每个 Python 类实例都有一个命名空间。这是一个存放值的地方。命名空间是一个字典。你可以通过 __dict__ 查看它。当你请求 my_dog.name 时,Python 会在实例的命名空间中查找。如果在那里没有找到该名称,它会检查类。

Python 使用实例的命名空间来保存其值。

class Dog:
    kind = "canine"

my_dog = Dog()
my_dog.name = "Fido"

print(my_dog.name)
# 输出: Fido
print(my_dog.kind)
# 输出: canine
print(my_dog.__dict__)
# 输出: {'name': 'Fido'}

Python是如何为类实例查找方法的?

当你使用类似 my_dog.bark() 的方法时,Python会在类中查找该方法。如果这是一个用户定义的函数,Python会将其封装为一个方法,并将实例作为第一个参数添加。

当从实例调用时,Python会将类函数封装为方法。

class Dog:
    def bark(self):
        return "汪汪!"

d = Dog()
print(d.bark())
# 输出: 汪汪!

bark(self) 中,self 指的是 d。当你调用 d.bark() 时,Python 会将 d 作为第一个参数传递。

类实例可以像函数或列表一样工作吗?

可以。Python 类实例可以假装成许多东西。如果类中有一个名为 __call__ 的方法,那么你可以像调用函数一样调用该实例。如果类中有像 __getitem__ 这样的函数,它可以像列表或映射一样工作。

如果类定义了 call,Python 允许类实例像函数一样工作。

class Greeter:
    def __call__(self, name):
        return f"Hello, {name}!"

g = Greeter()
print(g("Ada"))
# 输出: Hello, Ada!

Python 类实例的历史时间线

Python 的类实例规则来自哪里?

Python 类实例源于面向对象设计。早期语言塑造了对象如何存储数据、运行代码以及像内置类型一样进行操作。Python 使这一切变得清晰、灵活且易于使用。


人们设计了使用对象类型的系统

1967 — Simula 类实例 Simula 引入了类实例作为具有自己数据的运行时对象。

1980 — Smalltalk 实例消息传递 Smalltalk 允许对象之间发送消息(方法调用)。

 

人们塑造了 Python 的模型

1991 — Python 0.9.0 添加类和实例 Python 支持基于类的设计,具有方法查找和实例存储。

2000 — Python 2.2 添加新式类 Python 允许所有类继承自 object,统一了方法处理和特殊方法。

人们扩展了实例的功能

2001 — 特殊方法改善实例行为 Python 2.2 支持丰富的比较、迭代和数值仿真。

2010 — 类装饰器和描述符 Python 3 使得控制实例设置和属性访问变得更加容易。

人们保持了 Python 实例的简单性和可预测性

2020 — 稳定的实例设计 Python 保持了实例处理的向后兼容性,使其简单且开放。

2025 — 最小变更 Python 保持实例规则不变,以保护可靠性。


Python 类实例的问题与解决方案

如何正确使用 Python 类实例?

Python 类实例帮助您创建存储数据和执行操作的对象。每个实例都有自己的值,并可以以特殊的方式进行操作。这些问题展示了 Python 类实例如何满足您代码中的实际需求。


问题:如何在 Python 中为不同的对象存储不同的值?

您正在制作一个游戏。每个玩家都有一个名字和一个分数。您希望每个玩家都能保留自己的值。

问题: 您需要一种方法来创建许多共享相同结构但保存不同数据的对象。

解决方案: 使用类来定义结构,然后为每个玩家创建一个新实例。

Python 允许您在每个实例中存储值。

class Player:
    def __init__(self, name, score):
        self.name = name
        self.score = score

p1 = Player("Ada", 10)
p2 = Player("Bob", 20)

print(p1.name, p1.score)
# prints: Ada 10
print(p2.name, p2.score)
# 输出: Bob 20

每个对象都有自己的名称和分数。这个类使之成为可能。


问题:如何在Python中对存储的数据执行操作?

你有一个计数器,用于跟踪用户点击的次数。你希望能够轻松地将总数加一。

问题:您需要一种存储数据并对其执行操作的方法。

解决方案:将数据放入实例中,并编写一个方法来更改它。

Python允许您添加方法以更改实例数据。

class Counter:
    def __init__(self):
        self.count = 0
    def click(self):
        self.count += 1

c = Counter()
c.click()
c.click()
print(c.count)
# 输出: 2

该方法使用 self 来改变对象的值。每个实例保持自己的计数。


问题:如何在Python中跨多个对象共享行为?

你在一个绘图工具中有许多形状。每个形状都有一个颜色。你希望所有形状都支持 paint() 操作。

问题:你需要给许多对象相同的方法,而不重复代码。

解决方案:使用一个类来定义该方法,然后创建共享该方法的实例。

Python允许你在类中定义共享方法。

class Shape:
    def paint(self, color):
        self.color = color

s1 = Shape()
s2 = Shape()

s1.paint("blue")
s2.paint("red")

print(s1.color)
# 输出: blue
print(s2.color)
# 输出: red

每个实例运行相同的方法,但存储自己的值。


问题:如何让对象在Python中表现得像内置类型?

您希望一个自定义对象,它的行为像列表,但能够跟踪每次访问。

问题:您希望您的类实例能够像列表一样响应 []

解决方案:定义 __getitem____setitem__ 来处理索引的使用。

Python允许类实例通过特殊方法表现得像列表。

class SpyList:
    def __init__(self):
        self.data = []
    def __getitem__(self, i):
        print(f"Getting item {i}")
        return self.data[i]
    def __setitem__(self, i, value):

print(f"设置项目 {i}{value}")
self.data[i] = value

s = SpyList()
s.data.append("a")
s[0] = "b"
print(s[0])
# 输出:
# 设置项目 0 为 b
# 获取项目 0
# b

这个实例看起来像一个列表,但增加了新的行为。


问题:如何在Python中跟踪对象状态随时间的变化?

你想创建一个可以在调用时运行的对象,就像一个小工具。

问题:你需要一个可以接受参数并返回结果的对象,就像一个函数一样。

解决方案:在你的类中添加一个 __call__ 方法。

Python允许类实例像函数一样工作。

class Adder:
def __init__(self, base):
    self.base = base
def __call__(self, x):
    return self.base + x

add5 = Adder(5)
print(add5(3))
# 输出: 8

该对象像函数一样运行,因为它定义了 __call__

更多