上一篇:self的使用 | 手把手教你入门Python之五十二
下一篇:有关运算的魔法方法 | 手把手教你入门Python之五十四
本文来自于千锋教育在阿里云开发者社区学习中心上线课程《Python入门2020最新大课》,主讲人姜伟。
魔法方法
Python ⾥有⼀种⽅法,叫做魔法⽅法。Python 的类⾥提供的,两个下划线开始,两个下划线结束的⽅法,就是魔法⽅法,魔法⽅法在恰当的时候就会被激活,⾃动执⾏。 魔法⽅法的两个特点:
- 两侧各有两个下划线;
- "咒语"名字已经由 Python 官⽅定义好,我们不能乱写。
1.__init__
⽅法
__init__()
⽅法,在创建⼀个对象时默认被调⽤,不需要⼿动调⽤。在开发中,如果希望在创建对象的同时,就设置对象的属性,可以对 __init__
⽅法进⾏改造。
class Person(object):
# 在创建对象时,会自动调用这个方法
def __init__(self, name, age):
print('__init__方法被调用了')
self.name = name
self.age = age
p = Person('zhangsan', 18)
执行结果:
class Cat:
"""这是⼀个猫类"""
def __init__(self,name): # 重写了 __init__ 魔法⽅法
self.name = name
def eat(self):
return "%s爱吃⻥"%self.name
def drink(self):
return '%s爱喝⽔'%self.name
"""
tom = Cat()
TypeError: __init__() missing 1 required positional argument: 'name'
这种写法在运⾏时会直接报错!因为 __init__ ⽅法⾥要求在创建对象时,必须要传递 name 属性
,如果不传⼊会直接报错!
"""
tom = Cat("Tom") # 创建对象时,必须要指定name属性的值
tom.eat() # tom爱吃⻥
注意:
-
__init__()
⽅法在创建对象时,会默认被调⽤,不需要⼿动的调⽤这个⽅法。 -
__init__()
⽅法⾥的self参数,在创建对象时不需要传递参数,python解释器会把创建好的对象引⽤直接赋值给self - 在类的内部,可以使⽤self来使⽤属性和调⽤⽅法;在类的外部,需要使⽤对象名来使⽤属性和调⽤⽅法。
- 如果有多个对象,每个对象的属性是各⾃保存的,都有各⾃独⽴的地址。
- ⽅法是所有对象共享的,只占⽤⼀份内存空间,⽅法被调⽤时会通过self来判断是哪个对象调⽤了实例⽅法。
2.__del__
⽅法
创建对象后,python解释器默认调⽤ __init__()
⽅法;
⽽当删除对象时,python解释器也会默认调⽤⼀个⽅法,这个⽅法为 __del__()
⽅法。
class Student:
def __init__(self,name,score):
print('__init__⽅法被调⽤了')
self.name = name
self.score = score
def __del__(self):
print('__del__⽅法被调⽤了')
s = Student('lisi',95)
del s
input('请输⼊内容')
执行结果:
3.__str__
⽅法
__str__
⽅法返回对象的描述信息,使⽤ print() 函数打印对象时,其实调⽤的就是这个对象的 __str__
⽅法。
class Cat:
def __init__(self,name,color):
self.name = name
self.color = color
tom = Cat('Tom','white')
# 使⽤ print ⽅法打印对象时,会调⽤对象的 __str__ ⽅法,默认会打印类名和对象的内存地址名
print(tom) # <__main__.Cat object at 0x0000021BE3B9C940>
如果想要修改对象的输出的结果,可以重写 __str__
⽅法。
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self):
return '哈哈'
p = Person('张三',18)
print(p) # 哈哈 打印对象时,会⾃动调⽤对象的 __str__ ⽅法
⼀般情况下,我们在打印⼀个对象时,可能需要列出这个对象的所有属性。
class Student:
def __init__(self,name,score):
self.name = name
self.score = score
def __str__(self):
return '姓名是:{},成绩是{}分'.format(self.name,self.score)
s = Student('lisi',95)
print(s) # 姓名是:lisi,成绩是95分
4. __repr__
⽅法
__repr__
⽅法和 __str__
⽅法功能类似,都是⽤来修改⼀个对象的默认打印内容。在打印⼀个对象时,如果两个方法都写了,则选择__str__
。如果没有重写 __str__
⽅法,它会⾃动来查找 __repr__
⽅法。如果这两个⽅法都没有,会直接打印这个对象的内存地址。
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __repr__(self):
return 'hello'
class Person:
def __repr__(self):
return 'hi'
def __str__(self):
return 'good'
s = Student('lisi', 95)
print(s) # hello
p = Person()
print(p) # good
datetime类:
import datetime
x = datetime.datetime(2020,2,24,16,17,45,200)
print(x) # 2020-2-24 16:17:45.000200
print(repr(x)) # __repr__方法 datetime.datetime(2020, 2, 24, 16, 17, 45, 200)
5. __call__
⽅法
对象后⾯加括号,触发执⾏。
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__方法被调用了')
obj = Foo() # 执⾏ __init__
obj() # 执⾏ __call__
def __call__(self, *args, **kwargs):
# args 是一个元组,保存(1,2)
# kwargs 是一个字典{fn=lambda x, y: x + y}
print('args={},kwargs={}'.format(args, kwargs))
fn = kwargs['fn']
return fn(args[0], args[1])
n = p(1,2,fn=lambda x, y: x + y)
print(n)
执行结果:
总结
- 当创建⼀个对象时,会⾃动调⽤
__init__
⽅法,当删除⼀个对象时,会⾃动调⽤__del__
⽅法。 - 使⽤
__str__
和__repr__
⽅法,都会修改⼀个对象转换成为字符串的结果。⼀般来说,__str__
⽅法的结果更加在意可读性,⽽__repr__
⽅法的结果更加在意正确性(例如:datetime模块⾥的datetime类)