我对类的定义及其用法有一个一般性的问题。下面的一本书的代码工作正常,但我有一般性的问题。
这里我们定义了一个Point类并创建了2个实例Point1&点2。在计算point2的距离时,我们如何传递point1对象?
不是point1是点对象,而是other_point被重新定义为变量。
我很困惑。
代码:
import math
class Point:
def move(self, x, y):
self.x = x
self.y = y
def reset(self):
self.move(0, 0)
def calculate_distance(self, other_point):
print("Inside calculating distance")
return math.sqrt(
(self.x - other_point.x)**2 +
(self.y - other_point.y)**2)
point1 = Point()
point2 = Point()
point1.reset()
point2.move(5,0)
print(point2.calculate_distance(point1))
答案 0 :(得分:5)
创建Point
对象时,会发生一些事情。
point1 = Point()
point2 = Point()
发生的一件事是属于Point
类的任何方法绑定。这意味着该方法中的一个参数是 fixed ,因此它始终引用创建的实例。我们来看看calculate_distance
的定义。
def calculate_distance(self, other_point):
print("Inside calculating distance")
return math.sqrt(
(self.x - other_point.x)**2 +
(self.y - other_point.y)**2)
您可以猜测哪个参数已修复。调用Point()
并创建实例时,self
的{{1}}参数是固定的,因此它始终引用该实例。所以每当你这样做时:
calculate_distnace
你做的相当于:
point1.calculate_distance(x)
每当你这样做时:
Point.calculate_distance(point1, x)
你做的相当于:
point2.calculate_distance(point1)
答案 1 :(得分:2)
这就是self
变量的作用。因此,当您进入类的定义时,可以使用self
来标识您试图操作其数据的对象。
例如,假设您有一个名为human的类(具有名为age
的成员变量),并且每年都要通过调用increment_age
函数来增加该人的年龄。然后,您可以编写以下代码:
class Human:
def __init__(self):
self.age = 0
def increment_age(self):
self.age += 1
>>> h = Human()
>>> print h.age
0
>>> h.increment_age()
>>> print h.age
1
所以你看,通过调用self
,你指的是对象本身。在您的示例中,这将转换为引用self
的{{1}}。
现在,假设在point1
类中,我们想要添加一个允许两个人战斗的功能。在这种情况下,一个人将不得不与另一个人战斗(假设与另一个人战斗会使你的生命增加一个并且将另一个人的生命减少一个)。在这种情况下,您可以在Human
类中编写以下函数:
Human
现在:
def fight(self, other_human):
self.age += 1
other_human.age -= 1
因此,您可以在此示例中看到>>> h1 = Human()
>>> h2 = Human()
>>> h1.age = 5
>>> h2.age = 3
>>> print h1.age
5
>>> print h2.age
3
>>> h1.fight(h2)
>>> print h1.age
6
>>> print h2.age
2
是h2
函数中的other_human
。
希望有所帮助
答案 2 :(得分:1)
根据您的代码,point2.calculate_distance(point1)
调用calculate_distance
,point2
引用的对象为self
,point1
引用的对象为{{ 1}}。
了解这些事情的一个好方法是使用可视化调试器,并在调用时检查堆栈帧中的值。
答案 3 :(得分:0)
在calculate_distance
内,other_point
是用于引用作为参数传递的任何对象的名称。