在Python中,有些名称很特别,开头和结尾都是两个下划线,其中很大一部分都是魔法方法的名称,比如__init__(),__new__()等。
1、__init__方法
也叫构造函数,是初始化方法,对象创建后自动调用。
class Person(object):
def __init__(self):
print('自动调用')
p = Person()
输出:
自动调用
构造函数还可以添加参数,参数可以有默认值。
class Person(object):
def __init__(self,age = 18):
self.age = age
p = Person(20)
print(p.age)
输出:
20
构造函数用于初始化新建对象,对大多数子类来说,除超类的初始化代码外,还需要有自己的初始化代码。重写构造函数时,必须调用超类(继承的类)的构造函数,否则可能无法正确地初始化对象。
如果继承类重写了构造函数,但是又未调用超类的构造函数,可能会导致继承类没有超类的属性,示例如下:
class Person(object):
def __init__(self,age = 18):
self.age = age
class Teacher(Person):
def __init__(self):
pass
t = Teacher()
print(t.age)
输出:
Traceback (most recent call last):
File "F:\test.py", line 11, in <module>
print(t.age)
^^^^^
AttributeError: 'Teacher' object has no attribute 'age'
继承类Teacher没有age属性。
解决方法是使用super(注:super只针对python3使用),有两种写法。
class Person(object):
def __init__(self,age = 18):
self.age = age
class Teacher(Person):
def __init__(self):
# super(Teacher, self).__init__() #第一种方式
super().__init__() #第二种方式
pass
t = Teacher()
print(t.age)
即便有多个超类,也只需调用函数super一次,前提是所有超类的构造函数也使用函数super。
实际上,它返回的是一个super对象,这个对象将负责为你执行方法解析。当你访问它的属性时,它将在所有的超类以及超类的超类等等中查找,直到找到指定的属性或引发AttributeError异常。
此外还有析构函数__del__,在对象销毁前被调用,这个一般用的比较少。
2、__add__方法
运算符重载,定义对象之间的加法操作,当使用+运算符时被调用,其他类似的还有__sub__减法操作等。
class Test(object):
def __init__(self, data):
self.data = data
def __add__(self, other):
return self.data + other.data
a = Test(3.3)
b = Test(6)
print(a + b)
3、__str__方法
定义打印对象时的字符串表示,只能在print的情况下才能输出具体想要的效果。
class Test(object):
def __init__(self, data):
self.data = data
def __str__(self):
return self.data
a = Test('abc')
b = Test('def')
print(a)
print(b)
print([a,b])
输出:
abc
def
[<__main__.Test object at 0x000001FE5D192A10>, <__main__.Test object at 0x000001FE5D192990>]
4、__repr__方法
定义打印对象时的字符串表示,不管是print还是直接运行的情况下,都能输出内容。
class Test(object):
def __init__(self, data):
self.data = data
def __repr__(self):
return self.data
a = Test('abc')
b = Test('def')
print(a)
print(b)
print([a,b])
输出:
abc
def
[abc, def]
5、__len__方法
定义该类的实例对象被len()调用时的行为
class Test(object):
def __init__(self, data):
self.data = data
def __len__(self):
return len(self.data)
print(len(Test('abc')))
输出:
3
6、__eq__方法
定义等于“==”操作符的方法,其他的还有__ne__不等操作符,__lt__小于操作符,__gt__大于操作符,__le__小于等于操作符,__ge__大于等于操作符。
class Test(object):
def __init__(self, data):
self.data = data
def __eq__(self, other):
return self.data == other.data
print(Test(3) == Test(7))
输出:
False
7、 __setitem__方法,使用索引给某个元素赋值
__getitem__方法,使用索引访问某个元素
__delitem__方法,使用索引删除某个对象
class Test(object):
def __init__(self):
self.dict = {}
def __setitem__(self, key, value):
self.dict[key] = value
def __getitem__(self, item):
return self.dict[item]
def __delitem__(self, key):
del self.dict[key]
t = Test()
t.dict['name'] = 'test'
t.dict['age'] = 18
print(t.dict)
print(t['name'])
del t['age']
print(t.__dict__)
输出:
{'name': 'test', 'age': 18}
test
{'dict': {'name': 'test'}}
8、__bool__方法
定义bool操作运算
class Test(object):
def __init__(self, age):
self.age = age
def __bool__(self):
if self.age > 30:
return True
else:
return False
t = Test(34)
print(bool(t))
输出:
True
9、__new__方法
负责创建类,是对象实例化时第一个调用的方法
class Test(object):
def __init__(self, age):
#print(id(self)) #3147759365328
print('调用init')
self.age = age
def __new__(cls, *args, **kwargs):
print('调用new') #调用new
#print(id(cls)) #3147757192192
obj = super().__new__(cls)
#print(id(obj)) #3147759365328
return obj
#print(id(object)) #140717592972784
#print(id(Test)) #3147757192192
t = Test(3)
输出:
调用new
调用init
调用过程看id打印值就清楚,首先t = Test(3)之后会调用__new__方法,__new__方法中调用了父类的__new__生成了一个对象并返回,__new__中的参数cls即代表的是当前类。
再次__init__获取到__new__返回的对象,即参数self,之后就开始初始化。
10、__dict__特殊属性
获得类对象或实例的所有属性和方法字典
class Test(object):
def __init__(self, age):
self.age = age
def __new__(cls, *args, **kwargs):
obj = super().__new__(cls)
return obj
t = Test(3)
print(Test.__dict__)
print(t.__dict__)
输出:
{'__module__': '__main__', '__init__': <function Test.__init__ at 0x000001D5D9FE8360>, '__new__': <staticmethod(<function Test.__new__ at 0x000001D5D9FE8400>)>, '__dict__': <attribute '__dict__' of 'Test' objects>, '__weakref__': <attribute '__weakref__' of 'Test' objects>, '__doc__': None}
{'age': 3}
关注公众号同步更新: