我在做代码学院流,我在 Ruby 方面有一点经验。我不明白为什么 check_angles(self)
函数需要 self
参数。
我感到困惑的原因是我不明白在调用函数时将 self 参数传递给函数的是什么。函数调用(代码块的最后一行)似乎隐式传递了 self,但该函数需要将 self 显式定义为参数。
这是为什么?
class Triangle(object):
def __init__(self, angle1, angle2, angle3):
self.angle1 = angle1
self.angle2 = angle2
self.angle3 = angle3
number_of_sides = 3
def check_angles(self):
sum_angles = self.angle1 + self.angle2 + self.angle3
if sum_angles == 180:
return True
else:
return False
tri = Triangle(45,34,78)
tri.check_angles(EMPTY BUT WHY)
最佳答案
这在 Python 中的工作方式是,一旦你用方法 bar(self)
实例化了一个类 Foo
,用于创建该方法的函数就被包装在一个instancemethod
类型的对象将其“绑定(bind)”到实例,因此调用 foo_inst.bar()
实际上会调用 Foo.bar(foo_inst)
.
class Foo(object):
def bar(self):
print "called bar on %s" % self
foo_inst = Foo()
# these 2 calls are equivalent
foo_inst.bar()
Foo.bar(foo_inst)
或者,交互地:
>>> Foo.bar
<unbound method Foo.bar>
>>> Foo().bar
<bound method Foo.bar of <__main__.Foo object at 0x10675ecd0>>
如您所见,bar
仍然直接附加到类,但它是一个未绑定(bind)方法,并且仍然有 self
参数,但是,当从 Foo
实例中检索方法对象时,它已成为一个绑定(bind)方法,其 self
参数已预先设置为实例您从中检索了方法对象。
这也是为什么 self
可以真正被称为任何你想要的东西的原因,例如 arg0
或 this
或 me
或 putin
等
事实上,在这个例子中,方法实际上是底层函数变得更加明显:
class Foo(object):
pass
def bar(arg0):
print "called bar with %s" % arg0
Foo.bar = bar
Foo().bar() # prints: called bar with <Foo object at 0x10675b2d0>
另见 Python 描述符@ https://docs.python.org/2/howto/descriptor.html了解这是如何实现的,以及您如何自己实现类似的方案。
关于python - self 参数是如何神奇地传递给实例方法的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23082509/