Ich war ein wenig überrascht, deshalb werde ich ein Code-Stück und eine kurze Erklärung schreiben.
sample.rb
class A
def a1
def a2
'a2'
end
'a1'
end
end
output1
irb(main):013:0> obj1 = A.new
=> #<A:0x00000002500198>
irb(main):014:0> obj1.a1
=> "a1"
irb(main):015:0> obj1.a2
=> "a2"
Wie Sie sehen können, definiert der Aufruf von a1 a2 dynamisch als Instanzmethode von A. Übrigens existiert a2 nur, wenn a1 aufgerufen wird.
output2
irb(main):009:0> obj2 = A.new
=> #<A:0x000000011b7398>
irb(main):010:0> obj2.a2
NoMethodError: undefined method `a2' for #<A:0x000000011b7398>
from (irb):10
from /usr/bin/irb:11:in `<main>'
Da a2 als Instanzmethode von A definiert ist (da es häufig von Instanzen von A referenziert wird), kann es für alle Objekte aufgerufen werden, bis das Programm beendet oder explizit aus A entfernt wird.
output3
irb(main):009:0> obj3 = A.new
=> #<A:0x00000001106f70>
irb(main):010:0> obj3.a1
=> "a1"
irb(main):011:0> obj3.a2
=> "a2"
irb(main):012:0> obj4 = A.new
=> #<A:0x00000001118888>
irb(main):013:0> obj4.a2
=> "a2"
Diese Geschichte finden Sie übrigens in Metaprogramming Ruby 2nd Edition, S. 111.
Wäre es so, als würde man dasselbe mit Python machen?
sample.py
class A:
def a1(self):
self.__class__.a2 = lambda cls: 'a2'
return 'a1'
output4
>>> obj1 = A()
>>> obj1.a1()
'a1'
>>> obj1.a2()
'a2'
>>> obj2 = A()
>>> obj2.a2()
'a2'
Wenn dies der Fall ist, habe ich immer noch das Gefühl, dass ich es gewaltsam mache und es ist sicher (?).