3.2.4 了解其他常用魔术方法

之前提到的__init__方法叫魔术方法,会在类被创建时自动调用,类似地,Python还有其他魔术方法,它们的名字和被调用的场合如表3.1所示。

表3.1 魔术方法

从表3.1里,我们能看到诸多魔术方法会在特定的场合下被触发。在如下的MagicFuncDemo.py案例中,我们将演示上述魔术方法的用法。


01 # coding=utf-8
02 class Car:
03     def __init__(self,price):
04         print("in __init__")
05         self.price = price
06     # 回收类的时候被触发
07     def __del__(self):
08         print("In __del__")
09     def __str__(self):
10         print("in __str__")
11         return "price is: "+str(self.price)
12     def __repr__(self):
13         print("in __repr__")
14         return "price is: "+str(self.price)
15     def __setattr__(self, name, value):
16         print("in __setattr__")
17         self.__dict__[name] = value  # 给类中的属性名分配值
18     def __getattr__(self, key):
19         print("in __getattr__")
20         if key == "price":
21             return self.price
22         else:
23             print("Calss has no attribute '%s'" % key)
24     def __eq__(self, obj):
25         print("in __eq__")
26         return self.price == obj.price
27 # 触发__init__和__setattr__
28 myCar = Car(10000)
29 # 触发__init__和__setattr__
30 peterCar=Car(20000)
31 print(myCar) # 触发 __str__
32 myCar.price = 20000 # 触发__setattr__
33 print(myCar==peterCar) # 输出True,触发__eq__方法
34 # 运行代码结束,释放两个Car实例时触发两次__del__

在第2行定义的Car类里,我们定义了若干魔术方法,在诸多魔术方法里,都有对应的print语句。在第28行和第30行,我们在创建两个Car实例时又有赋值动作,所以分别触发了__init__和__setattr__方法。

第31行是要输出myCar实例,这里会隐性地把myCar转换成字符串形式,所以会触发__str__方法。在第32行设置值,因此会触发__setattr__方法。在第33行通过==来比较两个对象,所以会触发__eq__方法,由于在该方法里制定了根据price来比较的规则,因此两个对象是相等的。最后,当代码运行结束后,在释放两个Car实例时会两次触发__del__方法。

在第31行打印myCar对象时,如果没有重写__str__方法,就会触发__repr__方法。大家可以尝试着把__str__方法注释掉,然后查看一下效果。

在Python语法里还有其他魔术方法,因为它们的使用频率没有本小节提到的魔术方法高,所以就不再额外讲述了。