Unterschied zwischen Ruby und Python in Bezug auf Variablen

Gültigkeitsbereich der lokalen Variablen

In Ruby liegen lokale Variablenreferenzen nur innerhalb des definierten Bereichs.

ruby


a = 1

def func
  puts a
end

func #=> error (undefined local variable)

In Python kann auch vom Nachkommenbereich aus darauf verwiesen werden.

python


a = 1

def func():
  print(a)

func() #=> 1

Selbst wenn der definierte Bereich verschwindet, wird die lokale Variable nicht gelöscht, solange auf sie vom untergeordneten Bereich verwiesen wird. Sie können diese Eigenschaft auch anwenden, um so etwas wie eine Klasse mit Instanzvariablen zu erstellen. Diese klassenähnliche instanzmethode wird als Abschluss bezeichnet.

python


def cls(): #Klassenartig
  x = {} #Instanz variabelartig

  def a(): #Schließung
    x['a'] = 1

  def b(): #Schließung
    x['b'] = 1

  def g(): #Schließung
    return x

  return a, b, g

#Der Bereich von x verschwindet, wenn der Funktionsaufruf endet
a, b, g = cls()
a(); b();
print(g()) #=> {'a': 1, 'b': 1}

Ständiger Verschluss

Selbst bei Rubin, wenn es eine Konstante ist, gibt es einen Verschluss. Bevor ich ein Beispiel gebe, möchte ich ein wenig Rubin erklären.

In Ruby werden Konstanten und Variablen auf völlig unterschiedliche Weise verwaltet. Der Umfang der Variablen ändert sich abhängig von der Funktionsdefinition (ohne Do-Syntax usw.) und der Klassendefinition. Andererseits ändert sich der Umfang der Konstanten nur in Moduldefinitionen (einschließlich Klassendefinitionen). Und die Suche nach Konstanten

Wenn ein Nest vorhanden ist, wird diese Konstante nacheinander in den Elementen dieses Nestes durchsucht. (Aus Automatisches Laden und Neuladen von Konstanten)

Dies geschieht auf diese Weise (im Fall einer offenen Klasse wird jedoch nicht gesucht). Das heißt, Konstanten können auch aus dem Nachkommenbereich referenziert werden.

Mit dieser Eigenschaft können Sie einen Abschluss vornehmen.

ruby


module A
  X = 'x' #Instanz variabelartig

  module B #Klassenartig
    def show #Schließung
      puts X
    end
  end
end

class C #Instanzartig
  extend A::B
end

C.show #=> x

Instanzmethode, die wie eine lokale Variable aussieht

Ein Verweis auf eine lokale Variable, deren Definition fehlt, kann tatsächlich ein Instanzmethodenaufruf ohne Argumente sein. Ich treffe mich sehr oft.

ruby


class C
  def hoge #Instanzmethode
    return "hoge"
  end

  def show
    fuga = "fuga"

    puts hoge #Instanzmethodenaufruf
    puts fuga #Lokale Variablenreferenz
  end
end

Darüber hinaus erleichtern die Klassenmakros attr_accessor, attr_reader und attr_writer das Erstellen von Instanzmethoden, die wie lokale Variablen aussehen. Die Substanz der Variablen ist eine Instanzvariable, deren Name im Argumentensymbol mit @ vorangestellt ist.

ruby


class C
  attr_accessor :hoge #Instanzvariable@Hoge ist die Substanz

  def initialize
    self.hoge = "hoge" #Instanzmethode hoge=Anruf
  end

  def show
    fuga = "fuga" #Definieren Sie die lokale Variable fuga&Initialisieren

    puts hoge #Rufen Sie die Instanzmethode hoge auf
    puts fuga #Siehe lokale Variable fuga
  end
end

C.new.methods.include?(:hoge) #=> true
C.new.methods.include?(:hoge=) #=> true

Im Fall von Python ist es leicht zu unterscheiden, da der Aufruf der Instanzmethode selbst angehängt ist und die Klammern des Funktionsaufrufs nicht weggelassen werden können. Stattdessen ist es schwieriger, zwischen Instanzmethodenaufrufen und Klassenmethodenaufrufen zu unterscheiden.

python


class C:
  def hoge(self):
    return "hoge"

  @classmethod
  def piyo(cls):
    return "piyo"

  def show(self):
    fuga = "fuga"

    print(self.hoge()) #Instanzmethodenaufruf
    print(fuga) #Lokale Variablenreferenz

    print(self.piyo()) #Klassenmethodenaufruf

Mit lokalen Variablen überschreiben

(Hinzugefügt basierend auf Kommentaren von scivola)

Beim Aufruf der Instanzmethode hoge = im vorherigen Beispiel wurde self als Empfänger angegeben.

Rubin (Repost)


class C
  attr_accessor :hoge

  def initialize
    self.hoge = "hoge" #Hier
  end
  ...

Dies liegt daran, dass, wenn Sie nicht self angeben, dies als Definition der lokalen Variablen hoge behandelt wird.

ruby


class C
  attr_accessor :hoge

  def initialize
    hoge = "hoge" #Definition der lokalen Variablen hoge
  end

  def show
    puts hoge
  end
end

C.new.show #=> nil

Das gleiche kann mit Python passieren. Beispielsweise kann im Fall der zuvor eingeführten Klasse nicht die Instanzvariable nicht aktualisiert werden.

python


def cls():
  x = {} #Benimm dich wie eine Instanzvariable

  def u():
    x = 'updated' #Eigentlich ist die Definition der lokalen Variablen x

  def g():
    return x

  return u, g

#Der Bereich von x verschwindet, wenn der Funktionsaufruf endet
u, g = cls()
u();
print(g()) #=> {}

Sie können self in Python nicht auslassen, damit Sie beim Aktualisieren von Instanzvariablen keinen Fehler machen.

python


class C:
  def __init__(self):
    self.hoge = "not updated"

  def wrong(self):
    hoge = "updated" #Leicht zu erkennende Fehler

  def correct(self):
    self.hoge = "updated"

  def show(self):
    #print(hoge) #=> error (name 'hoge' is not defined)
    print(self.hoge)

c = C()
c.wrong(); c.show(); #=> not updated
c.correct(); c.show(); #=> updated

Beziehen Sie sich auf die einzuschließende Instanzvariable

ruby


module M
  def show
    puts @message
  end
end

class C
  include M
  def initialize
    @message = "accessible"
  end
end

C.new.show #=> accessible

Mit Python können Sie etwas Ähnliches tun.

python


class S:
  def show(self):
    print(self.message)

class C(S):
  def __init__(self):
    self.message = "accessible"

C().show() #=> accessible

Weisen Sie einer Variablen eine Funktion zu

In Ruby können Sie die Klammern des Funktionsaufrufs weglassen. Daher ist es nicht möglich, einer Variablen eine Funktion zuzuweisen.

ruby


def func
  return "called"
end

a = func #Rufen Sie die Funktion func auf
puts a #=> called

Object # -Methode Mit der Instanzmethode können Sie eine Funktion in ein Methodenobjekt konvertieren und einer Variablen zuweisen.

ruby


def func
  return "called"
end

a = method(:func) #Zuweisung von Methodenobjekten
puts a #=> #<Method: main.func>
puts a.call #=> called

Andererseits können Sie in Python Variablen Funktionen zuweisen.

python


def func():
  return "called"

a = func #Zuordnung der Funktion func
print(func) #=> <function func at 0x...>

Recommended Posts

Unterschied zwischen Ruby und Python in Bezug auf Variablen
Unterschied zwischen Variablen und Selbst. Variablen in der [Python] -Klasse
Unterschied zwischen Ruby und Python Split
Unterschied zwischen list () und [] in Python
Unterschied zwischen == und ist in Python
Unterschiede zwischen Ruby und Python im Umfang
Unterschied zwischen Anweisungen (Anweisungen) und Ausdrücken (Ausdrücken) in Python
Unterschied zwischen @classmethod und @staticmethod in Python
Unterschied zwischen Anhängen und + = in der Python-Liste
Unterschied zwischen nicht lokal und global in Python
Über den Unterschied zwischen "==" und "is" in Python
[Python] Berechnung der Differenz von Datum und Zeit in Monaten und Jahren
Unterschied zwischen return, return None und no return description in Python
Unterschiede beim Schreiben von externem Quellcode zwischen Ruby und Python
Unterschied zwischen der Python2-Serie und der Python3-Serie dict.keys ()
[Python] Unterschied zwischen Funktion und Methode
Python - Unterschied zwischen exec und eval
[Python] Unterschied zwischen randrange () und randint ()
[Python] Unterschied zwischen sortiert und sortiert (Colaboratory)
Python-Modul num2words Verhaltensunterschied zwischen Englisch und Russisch
Listenverkettungsmethode in Python, Unterschied zwischen list.extend () und dem Operator "+"
Referenzreihenfolge von Klassenvariablen und Instanzvariablen in "self. Klassenvariablen" in Python
[Python] Stärken und Schwächen von DataFrame in Bezug auf den Zeitaufwand
Unterschied in der Authentizität zwischen Python und JavaScript
Großer Unterschied in der Leistung von Ruby, Python und httpd
Unterschiede zwischen Python- und Java-Syntax
Unterschiede in der Beziehung zwischen PHP und Python schließlich und beenden
[Python] Unterschied zwischen Klassenmethode und statischer Methode
[Python Iroha] Unterschied zwischen Liste und Tupel
[Python] Unterschied zwischen Rand- und Randn-Ausgabe
Unterschiede in der Multithread-Verarbeitung zwischen Python und Jython
Funktion zum Öffnen einer Datei in Python3 (Unterschied zwischen open und codecs.open und Geschwindigkeitsvergleich)
Unterschied zwischen Ruby und Python (grundlegende Syntax)
Projekt Euler # 1 "Vielfaches von 3 und 5" in Python
Zusammenfassung der Korrespondenz zwischen Ruby- und Python-Array-Operationen
Die Antwort von "1/2" unterscheidet sich zwischen Python2 und 3
Angeben des Bereichs von Ruby- und Python-Arrays
[Python] Kapitel 02-01 Grundlagen von Python-Programmen (Operationen und Variablen)
Projekt Euler # 6 "Differenz in der Summe der Quadrate" in Python
Über flache und tiefe Kopien von Python / Ruby
Erläuterung der Bearbeitungsentfernung und Implementierung in Python
Vergleich von Python und Ruby (Environment / Grammar / Literal Edition)
Ruby, Python und Map
Python und Ruby teilen sich
Unterschiede in der Zeichenfolgenverarbeitung zwischen Python, Ruby, JS und PHP (Kombination und Variablenerweiterung)
Ich habe die Geschwindigkeit regulärer Ausdrücke in Ruby, Python und Perl (Version 2013) verglichen.
Teilt die Zeichenfolge durch die angegebene Anzahl von Zeichen. In Ruby und Python.
"Lineare Regression" und "Probabilistische Version der linearen Regression" in Python "Bayes lineare Regression"
Verarbeitung von CSV-Daten in voller und halber Breite in Python
Berechnung der Standardabweichung und des Korrelationskoeffizienten in Python
AtCoder ARC080 D Simulation mit Ruby und Python gelöst
[Ruby vs Python] Benchmark-Vergleich zwischen Rails und Flask
Das Einrückungsverhalten von json.dumps unterscheidet sich zwischen python2 und python3
Ruby, Python-Codefragment Ausführung der Auswahl in Emacs
Gegenseitige Konvertierung zwischen JSON und YAML / TOML in Python
Prozessübergreifende Kommunikation zwischen Ruby und Python (POSIX-Nachrichtenwarteschlange)
Vergleiche "log and infininity" mit Gauche (0.9.4) und Python (3.5.1)