可能重複:
What is the difference between Ruby and Python versions of「self」?Ruby的自身對Python的自我
Ruby和Python是相似的語言,無論在各種情況下使用的self
關鍵字。 self
在各種語言中的含義是什麼,有什麼區別?
可能重複:
What is the difference between Ruby and Python versions of「self」?Ruby的自身對Python的自我
Ruby和Python是相似的語言,無論在各種情況下使用的self
關鍵字。 self
在各種語言中的含義是什麼,有什麼區別?
關於Python,我可以告訴你沒有什麼新東西。正如pst所說,self
作爲一種方法的第一個參數通常被傳遞。從Python docs
通常,方法的第一個參數稱爲self。這只不過是一個約定:名字self對Python來說絕對沒有特殊含義。但是,請注意,通過不遵循約定,您的代碼對其他Python程序員而言可能會不易讀取,並且可以想象,可能會編寫一個依賴於這種約定的類瀏覽器程序。
CRuby(或'MRI')有一些類似的情況發生在引擎蓋下。每個C延伸部可以限定(模塊/類/單)上的Ruby類的方法,通過使用
實際的實現函數總是以VALUE self
作爲它們的第一個參數,類比於Python成語。 self
在這些情況下指的是這個特殊的郵件已經發送到對象實例,也就是說,如果你有
person = Person.new
person.do_sth
和do_sth會發生在C中實現,那麼將有一個對應的C函數
VALUE
person_do_sth(VALUE self) {
//do something
return self;
}
每個這樣的實施具有返回,其涉及這樣的事實,每個方法調用或消息中發送(粘到Smalltalk的說法)一個VALUE
(Ruby對象的C-表示)中具有返回值紅寶石。 Ruby中沒有這樣的東西,例如void
函數。
儘管我們需要在低級C代碼中來回傳遞self
,但您不需要在Ruby代碼中這樣做,Ruby會爲您處理此問題。 self的當前值存儲在內部執行的當前線程上下文中,因此self
的存在被授予,消息「self」將始終評估爲某個對象。
由於Ruby的動態特性,被self
引用的該對象的實際值隨當前解釋的代碼的當前範圍而變化。運行此看到自己:
puts "#{self} - declared in global scope" # the 'top self' aka 'main'
class << self
puts "#{self} - 'main's singleton class" # main's singleton or 'eigenclass'
end
puts "Starting to interpret class A code"
class A
puts "#{self} - When do I get executed!?" # self is class A
class << self
puts "#{self} - And me!?" # now A's singleton class
def a # declaring method in class's singleton class results in class method
puts "#{self} - declared in singleton class" # it's A
end
end
def self.b
puts "#{self} - declared in class method" # self is class A again -> class method
class << self
puts "#{self} - declared in Class A's singleton class" # now it's Class A's singleton class
end
end
def c
puts "#{self} - declared in instance method" # self is instance of A
class << self
puts "#{self} - declared in instance's singleton class" # now it's the A instance's singleton class
end
end
end
puts "All so far has happened simply by interpreting A's code"
a = A.new
A.a
A.b
a.c
如果你想調用一個方法/從任何方面將消息發送到self
,你能做到這一點明確地(例如self.method
),或省略self
作爲接收器 - 那麼按照慣例,消息的隱含接收者將是self
。
對此的一個有趣的方面是Ruby對private
方法的解釋,該方法不同,例如,來自Java的概念private
。 Ruby的私人方法僅通過發送使用self
作爲隱式接收器的消息可調用,即
class A
def a
b
end
private
def b
puts "I'm private"
end
end
a = A.new
a.a # => I'm private
作品,而由
def a
self.b
end
替換方法的將引發異常。這意味着Java中很常見的東西
class A {
private boolean compareUs(A a1, A a2) { ... }
public boolean equals(A a1, A a2) {
return (a1.compareUs() == a2.compareUs());
}
}
在Ruby中不起作用。愚蠢的例子,但只是爲了說明這一點:在Java中,我們可以訪問同一類的其他實例的私有方法,這在Ruby中是不可能的,因爲我們只能訪問當前的私有方法self
。
最後,使事情複雜一點,instance_eval
和class_eval
函數也將在執行過程中更改self
的值。
善良。什麼小說;) – 2011-07-13 00:42:08
真棒的答案。謝謝:) –
「return(a1.compareUs()== a2.compareUs())」真的嗎? compareUs()方法需要2個參數 – hihell
Ruby和Python實際上非常不同的語言(雖然他們有許多相似之處),即使Ruby有可寫看起來像Python中的語法(以列入end
關鍵字);-)
Ruby是基於消息的(它受SmallTalk-80的嚴重影響)並且「消息」被髮送到對象。 Ruby支持一個隱式的接收器(明確稱爲self
)的給定範圍。在紅寶石self
不是一個變量,而是一個表達式,評估爲當前的對象上下文。
Python是基於財產的(因爲我缺乏一個更好的術語),因此與函數直接執行(而不是消息傳遞)執行時更類似於SELF和JavaScript。 Python沒有self
關鍵字,並且它僅僅是約定,self
被用作方法的第一個參數的名稱 - 這是Python在當前對象上下文周圍傳遞的方式。
快樂編碼。
在Python中,my_instance.a_method(an_argument)
只是MyClass.a_method(my_instance, an_argument)
的簡寫。這樣的MyClass.a_method
定義應該考慮兩個參數:
class MyClass(object):
def a_method(self, an_argument):
print self # self (the instance) is available in the method
由於PST說,使用變量名self
的僅僅是一個慣例。你也可以有
class MyClass(object):
def a_method(this_instance, an_argument):
print this_instance
和一切都會工作相同...但不這樣做。
Python沒有'self'關鍵字。它只被慣例使用。 –