Bei Smalltalk könnten sich im Gegensatz zu Python übrigens Klassen ihre methodDictionaries teilen, etwas das Ruby braucht, um Module-Includes zu implementieren. Das geht in Python AFAIK nicht.
Man kann __dict__ auf Klassen selbst manipulieren. Will man die Methoden einer Klasse auch schlicht auf eine andere kopieren, kann man sie als Funktionen definieren und dann explizit zuweisen, man kann aber auch alle Funktion über das "im_func" Attribut von Methoden extrahieren und types.MethodType benutzen um sich eine Methode für die eigene Klasse zu bauen.
Code: Alles auswählen
In [1]: from types import MethodType
In [3]: class A(object):
...: def foo(self):
...: print "Hallo!", self
...:
...:
In [4]: class B(object):
...: foo = A.foo.im_func
...:
...:
In [5]: B.bar = A.foo.im_func
In [6]: class C(object):
...: pass
...:
In [7]: c = C()
In [8]: c.foo = MethodType(A.foo.im_func, c, C)
In [9]: A.foo()
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
/home/str1442/<ipython console> in <module>()
TypeError: unbound method foo() must be called with A instance as first argument (got nothing instead)
In [10]: A().foo()
Hallo! <__main__.A object at 0x9b190cc>
In [11]: B().foo()
Hallo! <__main__.B object at 0x9b190cc>
In [12]: B().bar()
Hallo! <__main__.B object at 0x9b190cc>
In [13]: c.foo()
Hallo! <__main__.C object at 0x9b1922c>
Will man irgendwelche Magie veranstalten, kann man __dict__, isinstance auf MethodType und andere Typen aus dem types Module oder ähnliches benutzen. Man könnte aus __dict__ sogar ein property machen und so die vollkommene Macht darüber bekommen, mag aber sein das man da ein paar Dinge bei beachten muss.
Ein import in Python funktioniert anders. Er kopiert Referenzen. Ändere ich zur Laufzeit ein Python-Modul, welches bereits importiert wurde, dann ändert sich an der Importstelle nichts mehr. Bei Ruby hingegen teilen sich alle Klassen, die ein Modul importiert haben, dieses und Änderungen an dem Ruby-Modul wirken sich sofort aus.
Natürlich ändert sich der Inhalt eines Python Modules überall, wo es benutzt wird. Ein Modul wird in sys.modules (ist ein dict) gespeichert und an sich ist ein Modul nur eine Instanz von types.ModuleType. Nur wenn ein richtiges Modul (also eine .py Datei) geändert wird, ändert sie sich nicht sofort, dann muss man erst reload() benutzen oder das Modul selbsständig aus sys.modules löschen und es neu importieren. Aber Python soll schließlich auch nicht die Dateien auf dem Rechner andauernd überwachen.
Bei Python gibt es auch gar kein Konzept, Methoden nachträglich in Klassen einzufügen, um so das Verhalten der Exemplare zu ändern.
Doch, siehe oben, Klassen händeln das automatisch, und zu speziellen Instanzen kann man sich auch Methoden generieren. Zusätzlich steht einem die ganze Magie von Metaklassen, Klassendekoratoren und "Metafunktionen" (Funktionen, die eine Klasse zurückgeben und "name, bases, dict" als Parameter annehmen, und somit als __metaclass__ spezifiert werden können - im Grunde das gleiche wie Klassendekoratoren, aber übernehmen zusätzlich die Konstruktion) zur Verfügung. An __bases__ rumzubasteln geht auch, ja - man kann sogar die Klasse eines Exemplars ändern:
Code: Alles auswählen
In [19]: class A(object):
....: def foo(self):
....: print self
....:
....:
In [20]: class B(object):
....: def bar(self):
....: print self
....:
....:
In [21]: a = A()
In [22]: print a.__class__, a.foo()
<class '__main__.A'> <__main__.A object at 0x9b63eec>
None
In [23]: a.__class__ = B
In [24]: print a.__class__, a.bar()
<class '__main__.B'> <__main__.B object at 0x9b63eec>
None