Pyhton魔术方法与Java整理

Pyhton魔术方法与Java整理

  • 第一类:对象的“生老病死”(构造与析构)
  • 第二类:把自己伪装成“函数”
  • 第三类:字符串表示(调试神器)
  • 第四类:把自己伪装成“容器”(列表/字典)
  • 第五类:运算符重载(数学与比较)
  • 第六类:属性访问控制(Getter/Setter)
  • 第七类:上下文管理器(With语句)
  • 总结:一张表看懂 Python 的“潜规则”

Python 里这些被双下划线包裹的方法,官方名叫 Magic Methods(魔术方法),社区常叫 Dunder Methods(双下方法)。它们很像 Java 里的“特殊方法”,但比 Java 多得多,也更自由。

如果把 Java 比作“规矩森严的工厂”,Python 的这些魔术方法就是给对象开的“后门”,让你能伪装成内置类型(比如假装自己是函数、列表、字典)。

以下是 Python 中最核心、最常用的魔术方法分类大全,我特意加了大量 Java 对比,方便你理解:

第一类:对象的“生老病死”(构造与析构)

这是“构造函数”家族。

方法类比Java 含义
_name _()-区分「文件是被直接运行,还是被导入」
_new _(cls, …)-真正的构造函数(创建对象)。极少重写,多用于单例模式或不可变对象。
_init _(self, …)构造函数ClassName()初始化函数。对象创建后自动调用,用来赋初值。
_del _(self)finalize() 析构函数。对象被垃圾回收前调用(不推荐依赖它,因为GC时机不确定)。

Python 特色:__new __ 和 __init __ 分离。
• __new __ 负责“生孩子”(分配内存,返回对象)。
• __init __ 负责“养孩子”(给对象穿衣服、起名字)。
• __name __ Python 解释器运行一个.py文件时,会自动给这个文件对应的模块对象设置__name __属性:如果直接运行这个文件(比如python test.py):__name __会被设为字符串"__main __“。如果这个文件被其他文件import(比如import test):test.py的__name __就是文件名"test”。
最经典的用法:if __name __ == “__main __”:

第二类:把自己伪装成“函数”

方法类比Java 含义
__call __(self, …)Functional Interface让实例变得可调用。定义了这个方法,对象就能像函数一样加括号执行:obj()

第三类:字符串表示(调试神器)

Java 里靠@Override toString(),Python 有两个,分工明确。

方法类比Java 含义
__str __(self)toString()给用户看。执行 print(obj) 或 str(obj) 时调用。追求可读性。
__repr __(self)toString() (调试版)给开发者看。直接输入 obj 回车时调用。追求准确性(最好能用来重建对象)。

潜规则:如果只写一个,就写 __repr __。

第四类:把自己伪装成“容器”(列表/字典)

这是 Python 比 Java 灵活得多的一个地方。你可以让一个对象支持 obj[key]、len(obj) 这种操作。

方法类比Java 含义
__len __(self)size() / length()定义 len(obj) 的行为。
__getitem __(self, key)get(index) / get(key)定义 obj[key] 的读取行为。
__setitem __(self, key, val)put(index, val)定义 obj[key] = val 的写入行为。
__contains __(self, item)contains()定义 in 运算符的行为 (if x in obj)。

第五类:运算符重载(数学与比较)

Java 不允许运算符重载(除了 + 拼接字符串),Python 允许。

方法运算符含义
__add __(self, other)+加法
__sub __(self, other)-减法
__eq __(self, other)==相等
__lt __(self, other)<小于
__gt __(self, other)>大于

例子:

classVector:def__init__(self,x):self.x=xdef__add__(self,other):returnVector(self.x+other.x)v1=Vector(1)v2=Vector(2)v3=v1+v2# 这里自动调用 __add__

第六类:属性访问控制(Getter/Setter)

Java 里用 getX() 和 setX(),Python 用装饰器,但底层是这些方法。

方法类比Java 含义
__getattr __(self, name)-访问不存在的属性时调用(常用于动态代理)。
__setattr __(self, name, val)Setter设置属性时调用(慎用,容易死循环)。
__getattribute __(self, name)Getter访问任何属性时调用(比getattr更底层)。

第七类:上下文管理器(With语句)

对应 Java 的 try-with-resources。

方法类比Java 含义
__enter __(self)try(…)进入 with 代码块时调用。
__exit __(self, …)catch/finally退出 with 代码块时调用(无论是否异常)。

例子:

withopen('file.txt')asf:data=f.read()

这里自动调用了 f.__enter __() 和 f.__exit __()

总结:一张表看懂 Python 的“潜规则”

  • 如果你想让对象实现这个方法
  • 像函数一样被调用 __call __
  • 用 print() 打印好看 __str __
  • 用 len() 取长度 __len __
  • 用 obj[key] 取值 __getitem __
  • 用 obj1 + obj2 相加 __add __
  • 用 with 管理资源 __enter __, __exit __
  • 支持 for…in… 循环 __iter __, __next __

一句话总结:Java 的“特殊方法”是语言规定死的;Python 的魔术方法是开放的协议,只要你实现了特定的双下方法,你的对象就能获得对应的“超能力”。