簡體   English   中英

自我論證如何神奇地傳遞給實例方法?

[英]How is the self argument magically passed to instance methods?

我正在做代碼學院流,我有一點Ruby經驗。 我不明白為什么check_angles(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類型的對象中,該對象將它“綁定”到實例,以便調用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是一個未綁定的方法 ,但仍然有self參數,但是,當從Foo實例檢索方法對象時,它已成為一個綁定方法,self參數已經預先-set到從中檢索方法對象的實例。

這也是為什么self可以被稱為任何你想要的東西,如arg0 (或stifflersmomallyourbase )。

另請參閱 Python描述符@ https://docs.python.org/2/howto/descriptor.html ,了解其實現方式以及如何自行實現類似方案。


事實上,在這個例子中,方法實際上是功能更加明顯:

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>

注意:在聲明了類對象之后將它們分配給類對象(稱為monkeypatching)並不是動態語言(如Python)中推薦的編程風格,因為它是A)容易出錯(可能會覆蓋同一類的未來版本中的某些內容,因為沒有編譯器來驗證不是這種情況)和B)難以理解(不可能通過查看類定義來知道類的實例具有哪些實例,因為沒有編譯器/ IDE來查找添加的方法)。

當你調用tri.check_angles()你會感到困惑,因為函數check_angles只有一個參數。 事實上,你是對的。 tri是作為self傳遞的論證。

self在類中用於保存類的特定實例的本地變量。

class A():
    def __init__(self):
        self.x = 2

>>> a = A()
>>> b = A()
>>> print a.x
2
>>> print b.x
2
>>> a.x = 5
>>> print a.x
5
>>> print b.x
2

然而,如果您只有x而不是self.x並且您為一個實例更改了x的值,則所有實例的x將更改。

希望有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM