- Python中的魔术方法是由官方定义好的,它们会在合适的时机被自动调用。
- 魔法方法的形式:以两个下划线开始并以两个下划线结束。举例:
__init__
本篇先介绍__init__
,__del__
,__str__
,__repr__
,__call__
五个魔术方法
点击查看下一篇Python的魔术方法(魔法方法)(二)
__init__
方法
__init__
方法,在创建一个新对象时被自动调用。
如果希望在创建对象的同时,就设置对象的属性,可以对__init__
方法进行修改。
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
# 在创建时,必须指定属性name和age的值
person1 = Person('燕小六', 28)
注意
__init__
方法里的参数self
参数在创建对象时不需要传递参数。Python解释器会把创建好的对象引用直接赋值给self
。- 对于多个实例而言,实例的属性单独保存,有各自独立的内存地址。
- 在类的内部,可以使用
self
来使用属性好调用方法;在类的外部,需要使用对象名来使用属性和调用方法。 - 方法是所有对象共享的,只占用一份内存空间,方法被调用时会通过
self
来判断是哪个对象调用了实例方法。
__del__
方法
当删除对象时,python解释器会默认调用__del__
方法。
class Person():
def __init__(self, name, age):
print('__init__方法被调用了')
self.name = name
self.age = age
def __del__(self):
print('__del__方法被调用了')
s = Person('邢捕头', 34)
del s
print(1)
运行结果:
__init__方法被调用了
__del__方法被调用了
1
如果删除最后两行语句,运行结果为下:
__init__方法被调用了
__del__方法被调用了
当程序运行结束后,系统会自动回收内存,自动调用__del__
方法删除实例。
__str__
方法
__str__
方法在两种情况下会被调用:
- 直接对实例使用
print()
语句 - 对实例使用
str()
直接对print(实例)
情况
一般情况下,直接对实例使用print()
语句,输出结果是<__main__.类名 object at 内存地址>
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
s = Person('邢捕头', 34)
print(s) # <__main__.Person object at 0x0000029A23F1A488>
如果我想让打印实例的结果是指定内容,需要如何修改?
重写__str__
方法,并将返回指定内容,必须是字符串!
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return 'Hello'
s = Person('邢捕头', 34)
print(s) # Hello
对实例使用str()
情况
对实例对使用str()
,再输出的结果也是<__main__.类名 object at 内存地址>
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
s = Person('邢捕头', 34)
a = str(s)
print(a) # <__main__.Person object at 0x00000221C741A488>
假如你需要让转成字符串的实例对象的输出结果是指定内容,也是重写__str__
方法。
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return 'Hi'
s = Person('邢捕头', 34)
a = str(s)
print(a) # Hi
当然,有时候我们的需求往往比仅仅输出Hello或Hi要复杂。
在重写方法时,我们仍可以调用实例和类的属性,一般使用__str__
来输出实例的属性。
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return 'name:{} age:{}'.format(self.name, self.age)
s = Person('邢捕头', 34)
a = str(s)
print(a) # name:邢捕头 age:34
__repr__
方法
__repr__
方法和__str__
方法功能类似,都是用来修改一个对象的默认打印内容。在打印一个对象时,如果没有重写__str__
方法,它会自动来查找__repr__
方法。如果这两个方法都没有,会直接打印这个对象的内存地址。
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return 'Hi'
class Student():
def __init__(self, name, score):
self.name = name
self.score = score
def __repr__(self):
return 'Hi'
def __str__(self):
return 'Hello'
a = Person('邢捕头', 34)
print(a) # Hi
b = Student('白展堂', 98)
print(b) # Hello
注意:
一般来说,__str__
方法的结果更加在意可读性,而__repr__
方法的结果更加在意正确性。
__call__
方法
当对实例后面直接加括号时,python将自动调用__call__
方法。
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
def __call__(self, *args, **kwargs):
print('__call__被调用了')
a = Person('邢捕头', 34)
a()
运行后将输出:
__call__被调用了
我们可以利用修改__call__
方法使其实现复杂功能。