可能重复:
What is the difference between Ruby and Python versions of“self”?
Ruby和Python是类似的语言,它们在各种情况下都使用self
关键字。 self
在每种语言中的含义是什么,有什么区别?
答案 0 :(得分:15)
Ruby和Python实际上是非常不同的语言(尽管它们确实有许多相似之处),即使Ruby的语法可以编写为类似Python(包含end
关键词); - )
Ruby是基于消息的(它受SmallTalk-80的影响很大),“消息”被发送到对象。 Ruby支持给定范围的隐式接收器(明确称为self
)。在Ruby中self
不是变量,而是一个计算当前对象上下文的表达式。
Python是基于属性的(因为我知道缺少一个更好的术语),因此更像是SELF和JavaScript,因为函数是直接执行的(而不是传递的消息)。 Python没有self
关键字,只是self
被用作方法的第一个参数的名称的惯例 - 这就是Python传递当前对象的方式上下文。
快乐的编码。
答案 1 :(得分:9)
在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
并且一切都会起作用......但不要这样做。
答案 2 :(得分:9)
关于Python我可以告诉你什么新内容。传统上,self
作为方法的第一个参数传递,正如pst所说。来自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;
}
每个这样的实现都有来返回VALUE
(Ruby对象的C表示),这与每个方法调用或消息发送(坚持Smalltalk用语)在Ruby中有一个返回值。 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
方法的解释,这些方法不同,例如来自private
的Java概念。 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
有效,而用
代替方法adef 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
的值。