魔术方法

Python 中的魔术方法(Magic methods)是一种特殊的方法,它们以双下划线(underscore)开头和结尾,例如 __init__()__str__() 等。这些方法在特定的情况下会被 Python 解释器自动调用,用于执行特定的操作,如初始化对象、打印对象、进行比较等。以下是一些常用的魔术方法及其作用:

  1. __init__(self, ...): 构造方法,用于初始化对象的状态。
  2. __del__(self): 析构方法,在对象被销毁时调用,通常用于释放资源。
  3. __repr__(self): 返回对象的“官方”字符串表示,通常是一个可以用于重新创建对象的表达式。
  4. __str__(self): 返回对象的“非正式”字符串表示,通常是用于用户阅读的格式。
  5. __len__(self): 返回对象的长度,可用于内置的 len() 函数。
  6. __getitem__(self, key): 定义对象的索引操作,用于获取元素。
  7. __setitem__(self, key, value): 定义对象的索引赋值操作,用于设置元素。
  8. __iter__(self): 返回对象的迭代器,用于支持迭代。
  9. __next__(self): 定义迭代器的下一个元素。
  10. __contains__(self, item): 定义对象包含成员关系操作,用于判断对象是否包含某个元素。

这些方法能够使你的自定义类对象在使用 Python 内置函数或进行操作时表现得更加符合预期。同时,你也可以根据自己的需求实现其他魔术方法来定制你的类的行为。

repr

__repr__ 是 Python 中一个特殊的方法(也称为魔术方法),用于定义对象的“官方”字符串表示形式。它通常被用于在调试和开发过程中提供对象的有用信息,以便更容易理解对象的状态。

当你在控制台中直接输入一个对象名并按下回车时,Python 解释器会调用该对象的 __repr__ 方法来获取其字符串表示形式,并将其显示在屏幕上。这个字符串应当足够清晰明了,以便理解对象的类型和状态。

下面是一个简单的例子,演示了如何定义 __repr__ 方法:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Point({self.x}, {self.y})"

在这个例子中,__repr__ 方法返回一个包含点的横纵坐标的字符串,格式为 "Point(x, y)"

使用示例:

p = Point(3, 4)
print(p)  # 输出: Point(3, 4)

注意:__repr__ 应当返回一个字符串,该字符串能够被解释器直接执行以创建一个和原对象状态一致的新对象。这意味着,最好返回的字符串是一个能够准确地表示对象状态的表达式。

str

__str__ 是一个 Python 类中的特殊方法(也称为魔术方法),用于返回对象的字符串表示形式。当你使用内置的 str() 函数或者打印一个对象时,Python 会自动调用该方法。

让我们详细解释一下 __str__ 方法的作用和用法:

  1. 返回字符串表示形式: __str__ 方法应该返回一个描述对象的字符串。这个字符串可以是任何有意义的描述,它应该简洁而清晰地说明对象的内容。通常情况下,返回的字符串应该是用户友好的,方便阅读。

  2. 可读性和可用性: 返回的字符串应该提供足够的信息以便理解对象的状态和属性。这对于调试和理解代码是非常有帮助的。

  3. repr 的区别: __repr__ 方法是另一个返回对象字符串表示形式的特殊方法。它的目的是返回一个尽可能准确的字符串表示形式,通常用于调试和开发过程中。而 __str__ 方法则更适合提供用户友好的输出,所以通常情况下应该实现 __str__ 方法。

总之,__str__ 方法提供了一种方便的方式来定义对象的字符串表示形式,使其更易于理解和使用。

示例1

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):
        return f'Point(x={self.x}, y={self.y})'

## 创建一个 Point 对象
p = Point(3, 4)

## 打印该对象
print(p)  # 输出: Point(x=3, y=4)

## 使用 str() 函数获取对象的字符串表示形式
str_representation = str(p)
print(str_representation)  # 输出: Point(x=3, y=4)

在这个例子中,__str__ 方法返回了一个描述点坐标的字符串,包含了 xy 的值。

示例2

class Student(Model):
    id = Field(pk=True, nullable=False)
    name = Field(fieldname='username', nullable=False)
    age = Field(nullable=True)

    def __repr__(self):
        return '<Field {{} {} {}}>'.format(
            self.id, self.name, self.age
        )

    __str__ = __repr__

这里是将 __str__ 方法设置为 __repr__ 方法,这意味着在调用 str() 函数或者直接打印对象时,都会使用 __repr__ 方法的实现来获得对象的字符串表示形式。

这种方法适用于许多情况下,特别是在你希望 __str____repr__ 返回相同的字符串表示形式时。它减少了代码的重复,并确保两个方法的输出保持一致。

总的来说,这是一种有效的方法来定义对象的字符串表示形式,尤其适用于简单的情况,例如你所示的 Student 类。