Само по себе Ruby и сам Python

Возможный дубликат:
В чем разница между версиями «self» Ruby и Python?

Ruby и Python – это аналогичные языки, которые имеют ключевое слово self используемое в различных ситуациях. Что означает self на каждом языке, и каковы различия?

3 Solutions collect form web for “Само по себе Ruby и сам Python”

Что касается Python, я не могу сказать вам ничего нового. self оно принято условно как первый параметр метода, как сказал pst. Из документов Python

Часто первый аргумент метода называется «я». Это не что иное, как соглашение: имя «я» совершенно не имеет особого значения для Python. Обратите внимание, однако, что, не соблюдая соглашение, ваш код может быть менее читаемым для других программистов на Python, и также возможно, что программа браузера классов может быть написана, которая опирается на такое соглашение.

У CRuby (или «MRI») есть нечто похожее, которое происходит под капотом. Каждое расширение C может определять методы (module / class / singleton) в классе Ruby, используя

  • rb_define_method (экземпляр)
  • rb_define_singleton_method (singleton class)
  • rb_define_module_function (класс / модуль)

Фактические функции реализации всегда принимают 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 (представление C объекта Ruby), что связано с тем, что каждый вызов метода или сообщение, отправленное (придерживаться языка Smalltalk), имеет возвращаемое значение в Ruby. В Ruby нет такой функции, как функция void .

Хотя нам нужно передавать self взад-вперед в низкоуровневом коде C, вам не нужно делать это в 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 Aa Ab ac 

Если вы хотите вызвать метод / отправить сообщение из любого контекста в 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 aa # => I'm private 

работает, тогда как замена метода a на

 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, потому что мы можем получить доступ только к закрытым методам текущего пользователя.

Наконец, чтобы усложнить ситуацию немного, функции instance_eval и class_eval также class_eval значение self во время выполнения.

Ruby и Python на самом деле очень разные языки (хотя они действительно имеют много общего), даже если Ruby имеет синтаксис, который может быть написан, чтобы выглядеть как Python (с включением end ключевых слов) 😉

Ruby основан на сообщениях (на него сильно повлияло SmallTalk-80), а «сообщения» отправляются на объекты. Ruby поддерживает неявный приемник (явно известный как self ) для данной области. В Ruby 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-метод без его явного принятия
  • Python - лучший язык программирования в мире.