__init__方法
如果一个Python方法以双下划线作为开始和结束标志,这表明这是一个特殊的方法,你可以把它理解成Python内置方法,所以自己在自定义方法的时候避免这样定义方法。
对象初始化
大部分面向对象语言都有一个叫做构造函数的特殊方法,当它被创建的时候就会创建和初始化对象。这里Python和它们有一点点不同,Python有一个构造函数和一个初始化函数。在大部分情况下,构造函数很少能用得到,这里我们着重来看下类的初始化函数。
类的初始化函数除了一个特殊的名字外,和其他方法没有什么不同。
一、创建一个类(class)
在Python中,可以通过class关键字定义自己的类(class),然后通过自定义的类创建实例对象。
最简单的类如下:(不包含任何属性和方法)
class FirstClass:
pass
利用这个类创建两个对象a和b,并打印:
a = FirstClass()
b = FirstClass()
print(a)
print(b)
结果为
<__main__.FirstClass object at 0x00000183514FCB00>
<__main__.FirstClass object at 0x00000183514FC080>
这说明a和b位于不同的内存区域,因此是两个对象。
二、查看类的继承
可以调用__bases__方法查看一个类的父类,
FirstClass.__bases__
得到
(object,)
说明FirstClass继承了object类。
- 在Python3中,所有类都默认继承object,因此object是所有类的父类。这一点与Java是相同的。
- 但是Python中允许一个子类继承多个父类,而Java要求一个子类只能继承一个父类。
- Python和Java都允许一个父类可以被多个子类继承。
想要更具体地了解Python类的继承,请查阅引用[2]PYTHON3中 类的继承 。
注意:
(1) 在这里,__bases__和__init__都是Python内置方法,标志是以__为起止符号。__name__也一样。
(2) __bases__只能被class调用,不能被对象调用,如下所示。
三、利用点记法给类添加属性
上述FirstClass类不包含任何属性和方法,我们可以通过点记法对**类的实例化对象(instance)**进行属性添加:
<object>.<attribute>=<value>
其中 value 可以是 Python 的内置数据类型、其他的对象,也可以是一个函数或者另一个类。
c = FirstClass()
d = FirstClass()
c.atr = 1
d.atr = 2
d.btr = 3
print(c.atr)
print(d.atr)
print(d.btr)
输出
1
2
3
- 可以给一个对象添加一个或多个属性,例如上面的atr和btr。
- 属性能够重新赋值。
d.btr = 4
print(d.btr)
4
四、添加方法
现在为上面的FirstClass类添加属性和方法,属性包括x和y坐标,方法包括2个:reset 重置坐标到原点(0,0)和 rightmove2右移2个单位。**
用def定义了一个类方法,它和普通函数有一点不同,就是它有一个self参数。
方法中的这个self参数,就是对调用该方法(method)的实例对象(instance)的一个引用(reference)。
class FirstClass:
def reset(self):
self.x = 0
self.y = 0
def rightmove2(self):
self.x = 2
self.y = 0
创建FirstClass的实例对象p,给属性赋值并调用方法:
p = FirstClass()
p.x = 1
p.y = 2
print(p)
print(p.x)
print(p.y)
输出为
<__main__.FirstClass object at 0x00000183515F2B38>
1
2
调用reset方法:
p.reset()
print(p)
print(p.x)
print(p.y)
输出为
<__main__.FirstClass object at 0x00000183515F2B38>
0
0
调用rightmove2方法:
p.rightmove2()
print(p)
print(p.x)
print(p.y)
输出为
<__main__.FirstClass object at 0x00000183515F2B38>
2
0
可见,p所在的内存位置保持不变,因此都是同一个对象。
用def定义了一个类方法,它和普通函数有一点不同,就是它有一个self参数。
方法中的这个self参数,就是对调用该方法(method)的实例对象(instance)的一个引用(reference)。
在这里,self 指对调用 reset 和 rightmove2 方法的实例对象 p 的一个引用。
你注意到我们调用p.reset()方法时候,并没有给它传入self参数。这里是Python帮我们自动传入:它知道我们正在调用p对象的一个方法,所以会自动把这个对象 p 传入这个方法 reset。也就是说:p.reset()
等价于 Point.reset(p)
。
因此,Python 会自动把调用某个类的方法的对象作为 self 参数传入该方法。
下面实现一个简单的计算两点间距离的类:
import math
class Point:
def move(self, x, y):
self.x = x
self.y = y
def reset(self):
self.move(0, 0)
def distance(self, other):
return math.sqrt((self.x - other.x) ** 2 + (self.y - other.y) ** 2)
创建对象并调用方法。传参只需要考虑一般参数,无须显示地传入self参数,Python会自动将调用方法的对象传入self参数。
p1 = Point()
p2 = Point()
p1.move(3, 4)
p2.move(5, 12)
print(p1.distance(p2))
print(p2.distance(p2))
结果为
8.246211251235321 # p1与p2之间的距离
0.0 # p2与自身的距离当然为0
将p1重置,再计算p1到p2的距离。
p1.reset()
print(p1.distance(p2))
13.0 # 距离变为13