Python 自参数是如何神奇地传递给实例方法的?
我正在做代码学院流,我在Ruby方面有一点经验。我不明白为什么Python 自参数是如何神奇地传递给实例方法的?,python,self,Python,Self,我正在做代码学院流,我在Ruby方面有一点经验。我不明白为什么check_angles(self)函数需要self参数 我感到困惑的原因是,我不明白在调用self参数时是什么将其传递给函数的。看起来函数调用(代码块的最后一行)是自隐式传递的,但函数需要自显式定义为参数 为什么会这样 class Triangle(object): def __init__(self, angle1, angle2, angle3): self.angle1 = angle1
check_angles(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)
调用
tri.check_angles()
时,您会感到困惑,因为函数check_angles
只包含一个参数。事实上,你是对的。tri
是作为self
传递的参数
self
在类中用于保存类的特定实例的局部变量
例子
然而,如果您只是使用x
而不是self.x
,并且您更改了一个实例的x
值,那么所有实例的x
值都会更改
希望这会有所帮助。在Python中的工作方式是,一旦您使用一个方法
bar(self)
实例化一个类Foo
,用于创建该方法的函数将被包装在类型为instancemethod
的对象中,该对象将其“绑定”到实例,以便调用Foo_inst.bar()
实际调用Foo.bar(Foo\u inst)
或者,以交互方式:
>>> Foo.bar
<unbound method Foo.bar>
>>> Foo().bar
<bound method Foo.bar of <__main__.Foo object at 0x10675ecd0>>
注意:在声明类对象后将函数分配给类对象(称为monkeypatching)不是Python等动态语言中推荐的编程风格,因为它容易出错(可能会在同一类的未来版本中覆盖某些内容,因为没有编译器来验证这一点)B)难以理解(仅通过查看类定义不可能知道类的实例实际包含哪些方法,因为没有编译器/IDE来查找添加的方法)。
self
不是函数参数。它表示“函数”是一个类方法。因此,您可以从刚才定义的method中访问类属性和其他方法。@AleksanderLidtke:应该使用术语实例方法;类方法/属性在Python中有非常特殊的含义;它们指的是用@classmethod
修饰的方法,以及在实际类对象上存储和调用的属性。@AleksanderLidtke:事实上,从技术上讲,self
只是一个函数参数;没有更多,也没有更少:)请看我的答案了解原因。@ErikAllik:)不太熟悉Python的“幕后”视角,很有趣。谢谢。还忘记了@classmethod
。也许类的方法更合适。
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>>
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>