详解Python常用内置方法:从__init__到__str__使用指南
不知道你们有没有过这样的经历?明明照着教程写了代码,运行出来的对象信息却像天书一样,这时候是不是特别想抓住电脑屏幕大喊:"你给我说人话!" 今天咱们就来破解这个谜题,聊聊那些能让对象乖乖听话的魔法方法。
(敲黑板)先记住一个铁律:所有带双下划线的内置方法,都是Python给咱们开的绿色通道。它们就像游戏里的快捷键,用对了能让你代码效率直接起飞!
一、__init__方法:对象的出生证明
每次创建对象时,你有没有好奇过,那些初始数据是怎么塞进去的?比如说咱们要创建一个学生档案:
python复制class Student: def __init__(self, name, age): self.name = name self.age = age + 1 # 这里偷偷加了1岁 tom = Student("Tom", 18) print(tom.age) # 输出19,惊不惊喜?
看到没,__init__就是个装配车间。不过这里有个坑要注意:??别在__init__里做复杂运算??,特别是涉及网络请求或者文件操作。新手常犯的错是把这里当成万能工具箱,结果初始化个对象要等半天。
二、__str__方法:对象的身份证
还记得开头说的"天书信息"吗?试试给你的对象加上这个:
python复制class Student: # ...省略其他代码... def __str__(self): return f"学生姓名:{self.name},实际年龄:{self.age}" print(tom) # 输出"学生姓名:Tom,实际年龄:19"
这时候你会发现打印对象终于能看懂了。??重要的事情说三遍:一定要返回字符串!返回字符串!返回字符串!?? 我见过有人在这里返回整数,结果程序直接崩溃,找bug找到怀疑人生。
三、__repr__方法:程序员的暗号
有时候你会发现,在调试时看到的对象信息和print出来的不一样。比如说:
python复制class Student: # ...省略其他代码... def __repr__(self): return f"
{id(self)} >" print(tom) # 学生姓名:Tom... print(repr(tom)) #
这两个方法的关系就像身份证和护照——??__str__给人看,__repr__给机器看??。但有个偷懒小技巧:如果只定义__repr__,print时会自动调用它。不过专业点的做法还是两个都写,毕竟装逼要装全套嘛。
四、__del__方法:对象的临终遗言
先声明啊,这个方法新手慎用!它会在对象被销毁时自动调用,但Python的垃圾回收机制就像个不靠谱的钟点工,你永远不知道它什么时候来打扫卫生。看个例子:
python复制class TempFile: def __del__(self): print("正在删除临时文件...") # 这里应该写删除文件的代码 file = TempFile() # 当这个对象不再被引用时,才会触发__del__
切记切记:??不要依赖__del__做重要操作??!我有次用它来关闭数据库连接,结果程序异常退出时根本没执行,数据库直接被锁死。血的教训啊朋友们!
五、__eq__方法:对象连连看
当你写下"a == b"的时候,Python其实在背后偷偷调用__eq__方法。比如说比较两个学生是不是同一个人:
python复制class Student: # ...省略其他代码... def __eq__(self, other): return self.name == other.name and self.age == other.age tom2 = Student("Tom", 19) print(tom == tom2) # 输出True
但这里有个隐藏关卡:??记得处理类型不一致的情况??!比如拿学生对象和字符串比较,不处理的话程序会直接崩溃。建议加上类型判断:
python复制def __eq__(self, other): if not isinstance(other, Student): return False return self.name == other.name and self.age == other.age
六、__getattr__方法:对象界的"查无此人"
这个魔法方法专治各种属性不存在的情况。比如咱们做个智能学生对象:
python复制class Student: # ...省略其他代码... def __getattr__(self, name): if name == "birth_year": return 2023 - self.age raise AttributeError(f"'Student' object has no attribute '{name}'") print(tom.birth_year) # 2004 print(tom.height) # 抛出AttributeError
用好了能实现动态属性,但??千万别滥用??!我见过有人用这个方法实现伪继承,结果代码比蜘蛛网还乱,最后他自己都理不清逻辑了。
说到最后,给各位新手朋友一个忠告:内置方法就像乐高积木,组合起来能造出各种神奇效果。但记住两点原则:
- ??不要重复造轮子??:能用现成的方法就别自己瞎折腾
- ??保持简单直白??:魔法方法不是越复杂越好,能解决问题才是王道
最近在教学生时发现,很多新手最大的问题不是不会写代码,而是总想着炫技。结果把简单的事情复杂化,最后代码变成一团乱麻。咱们学这些内置方法,目的是让代码更清晰易读,而不是给同事留下"这人代码真难懂"的印象,你说对吧?