全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-19 10 分钟 ✍️ juanwangdev

Python 魔术方法基础

魔术方法(Magic Methods)以双下划线开头和结尾,用于定制类的内置行为。

init:初始化

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


p = Person("Alice", 25)
print(p.name)  # Alice
print(p.age)   # 25

__init__ 在实例创建后自动调用,用于初始化实例属性。

strrepr

Python
class Product:
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def __str__(self):
        "用户友好的字符串表示"
        return f"{self.name}: ¥{self.price}"

    def __repr__(self):
        "开发者友好的表示,应能重建对象"
        return f"Product('{self.name}', {self.price})"


p = Product("苹果", 5.5)

# __str__ 用于 print 和 str()
print(p)           # 苹果: ¥5.5
print(str(p))      # 苹果: ¥5.5

# __repr__ 用于 repr() 和调试
print(repr(p))     # Product('苹果', 5.5)

# 在交互式环境中显示 __repr__
p  # Product('苹果', 5.5)

# 可重建对象
p2 = eval(repr(p))
print(p2.name)     # 苹果
方法用途触发时机
__str__用户友好显示print(obj)str(obj)
__repr__开发者友好显示repr(obj)、交互式显示

len

Python
class Bookshelf:
    def __init__(self, books):
        self.books = books

    def __len__(self):
        return len(self.books)


shelf = Bookshelf(["Python", "Go", "Java"])
print(len(shelf))  # 3

bool

Python
class Stack:
    def __init__(self):
        self.items = []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop() if self.items else None

    def __len__(self):
        return len(self.items)

    def __bool__(self):
        return len(self.items) > 0


stack = Stack()
print(bool(stack))  # False

stack.push(1)
print(bool(stack))  # True

if stack:  # 使用 __bool__
    print("栈非空")

getitemsetitemdelitem

Python
class DictLike:
    def __init__(self):
        self.data = {}

    def __getitem__(self, key):
        return self.data[key]

    def __setitem__(self, key, value):
        self.data[key] = value

    def __delitem__(self, key):
        del self.data[key]

    def __contains__(self, key):
        return key in self.data


d = DictLike()
d['a'] = 1        # __setitem__
d['b'] = 2
print(d['a'])     # 1 (__getitem__)
del d['b']        # __delitem__
print('a' in d)   # True (__contains__)
print('b' in d)   # False

iternext

Python
class Counter:
    def __init__(self, start, end):
        self.current = start
        self.end = end

    def __iter__(self):
        return self

    def __next__(self):
        if self.current >= self.end:
            raise StopIteration
        value = self.current
        self.current += 1
        return value


for num in Counter(0, 5):
    print(num)  # 0, 1, 2, 3, 4

eq 与其他比较方法

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

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

    def __lt__(self, other):
        return (self.x, self.y) < (other.x, other.y)

    def __le__(self, other):
        return self == other or self < other


p1 = Point(1, 2)
p2 = Point(1, 2)
p3 = Point(2, 1)

print(p1 == p2)  # True (__eq__)
print(p1 < p3)   # True (__lt__)
print(p1 <= p2)  # True (__le__)
方法操作符说明
__eq__==相等比较
__ne__!=不相等(默认使用 __eq__ 结果取反)
__lt__<小于
__le__<=小于等于
__gt__>大于
__ge__>=大于等于

hash

Python
class Card:
    def __init__(self, suit, rank):
        self.suit = suit
        self.rank = rank

    def __eq__(self, other):
        return (self.suit, self.rank) == (other.suit, other.rank)

    def __hash__(self):
        return hash((self.suit, self.rank))


c1 = Card("红桃", "A")
c2 = Card("红桃", "A")

# 可用作字典键和集合元素
cards = {c1: "王牌"}
cards[c2] = "也是王牌"
print(len(cards))  # 1(因为 c1 == c2)

s = {c1, c2}
print(len(s))      # 1

实现 __hash__ 的对象必须同时实现 __eq__,且相等对象的哈希值必须相同。

call

Python
class Multiplier:
    def __init__(self, factor):
        self.factor = factor

    def __call__(self, value):
        return value * self.factor


double = Multiplier(2)
print(double(10))  # 20(像函数一样调用)
print(type(double))  # Multiplier(仍是类实例)

new:创建实例

Python
class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

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


s1 = Singleton("first")
s2 = Singleton("second")
print(s1 is s2)     # True
print(s1.name)     # second(__init__ 再次调用)

__new____init__ 之前调用,负责创建实例对象。

del:析构

Python
class Resource:
    def __init__(self, name):
        self.name = name
        print(f"{self.name} 创建")

    def __del__(self):
        print(f"{self.name} 销毁")


r = Resource("资源A")
# 程序结束或 del r 时调用 __del__
del r  # 资源A 销毁

__del__ 不保证一定调用,建议使用上下文管理器管理资源。

enterexit

Python
class FileHandler:
    def __init__(self, filename):
        self.filename = filename

    def __enter__(self):
        self.file = open(self.filename, 'w')
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.file.close()
        return False  # 不抑制异常


with FileHandler('test.txt') as f:
    f.write("Hello")
# 自动关闭文件

常用魔术方法分类

类别方法
初始化__init____new__
字符表示__str____repr__
容器模拟__len____getitem____setitem____delitem__
迭代__iter____next__
比较__eq____lt____le____gt____ge__
哈希__hash__
可调用__call__
上下文__enter____exit__

要点总结

方法用途
__init__初始化实例
__str__用户显示
__repr__开发者显示
__len__len() 支持
__getitem__索引访问
__eq__== 比较
__call__函数式调用

魔术方法是 Python 的内置行为钩子,定制这些方法可改变类的默认行为。

D:\git2\jwdev\articles\PYTHON\进阶\面向对象编程\魔术方法基础.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 Python 运算符重载
下一篇 → Python functools 工具模块
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库