2009-11-25 8 views
8

Es scheint, dass Python bezüglich der Instanzmethoden einige Einschränkungen hat.Pythons Einschränkungen in Bezug auf Instanzmethoden überwinden

  1. Instanzmethoden können nicht kopiert werden.
  2. Instanzmethoden können nicht gebeizt werden.

Dies ist problematisch für mich, weil ich auf eine sehr objektorientierte project arbeiten, in dem ich Instanzmethoden verweisen, und es gibt die Verwendung von sowohl deepcopying und Beizen. Das Beizen geschieht meist durch den Multiprocessing-Mechanismus.

Was wäre ein guter Weg, um das zu lösen? Ich habe eine hässliche Umgehung des Kopierproblems gemacht, aber Ich suche eine bessere Lösung für beide Probleme.

Hat jemand irgendwelche Vorschläge?

Update:

Mein Anwendungsfall: Ich habe ein kleines Event-System. Jedes Ereignis hat ein .action Attribut, das auf eine Funktion zeigt, die es auslösen soll, und manchmal ist diese Funktion eine Instanzmethode eines Objekts.

+5

Normalerweise stellen wir den Code an allen Standorten zur Verfügung, an denen wir arbeiten, und verschieben lediglich eine Repräsentation des Staates. Repräsentation State Transfer ist häufiger und einfacher. Was stimmt damit nicht? –

+0

S.Lott, Sie haben eindeutig mehr Erfahrung mit diesem Thema, aber bitte erklären Sie es mir in einer dumpferen Art und Weise, was genau schlagen Sie vor, wie verhält es sich, was ist "Repräsentation State Transfer", etc. –

+0

Sie sagen "Ich möchte Instanzmethoden picken", aber Sie sagen nicht warum. Es würde uns helfen, zu wissen, welches Problem Sie lösen möchten, da es möglicherweise eine pythonischere Art gibt, es zu tun. Es klingt ein bisschen wie du in Ruby denkst ... –

Antwort

15

Sie könnten in der Lage sein, dies copy_reg.pickle mit zu tun. In Python 2.6:

import copy_reg 
import types 

def reduce_method(m): 
    return (getattr, (m.__self__, m.__func__.__name__)) 

copy_reg.pickle(types.MethodType, reduce_method) 

Dies speichert nicht den Code des Verfahrens, nur seinen Namen; aber das wird im allgemeinen Fall richtig funktionieren.

Dies macht sowohl Beizen als auch Kopieren möglich!

+0

Gute Idee, ich denke, es könnte die sauberste Lösung sein. Hast du eine Idee für das andere Problem, kopieren? Hat jemand bereits eine 'copy_reg'-Lösung implementiert, die ich verwenden kann? –

+0

Ich habe die Antwort bearbeitet und etwas Code hinzugefügt. –

3

REST - Darstellung Zustandsübertragung. Sende einfach State, nicht Methoden.

Um ein Objekt X von A nach B zu übertragen, tun wir dies.

  1. A codiert den Zustand von X in einem gewissen handlich, einfach zu Parse-Notation. JSON ist beliebt.

  2. A sendet die JSON Text B.

  3. B den Zustand des X-Form JSON Notation dekodiert, X.

B Rekonstruieren muss hierfür die Klassendefinitionen für die Klasse X haben arbeiten. B muss alle Funktionen und andere Klassendefinitionen haben, von denen die Klasse von X abhängt. Kurz gesagt, sowohl A als auch B haben alle Definitionen. Nur eine Darstellung des Objektstatus wird um verschoben.

Siehe einen Artikel auf REST.

http://en.wikipedia.org/wiki/Representational_State_Transfer

http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

+0

Können Sie mir bitte erklären, wie sich diese Methodik auf mein Problem mit dem Ereignissystem bezieht? –

+4

Dies ist eine "Du machst es falsch" Antwort. Diese Ansicht ist, dass "pickle" in Python vielleicht ein wenig * zu * praktisch ist; Es ist wirklich besser, Plain Old Data (im Gegensatz zu Objektdiagrammen) auszutauschen, da dies zu einfacheren Systemen führt, die seriöser sind. Da ist etwas dran, aber wenn es dir überhaupt hilft, wird es auf lange Sicht hilfreich sein. –

-3

Beize die Instanz und dann die Methode zuzugreifen, nachdem es Unpickling. Das Auswählen einer Methode einer Instanz ist nicht sinnvoll, da sie auf der Instanz beruht. Wenn nicht, schreibe es als unabhängige Funktion.

import pickle 

class A: 
    def f(self): 
     print 'hi' 

x = A() 
f = open('tmp', 'w') 
r = pickle.dump(x, f) 
f.close() 
f = open('tmp', 'r') 
pickled_x = pickle.load(f) 
pickled_x.f() 
+1

A() ist keine Instanzmethode. –

+1

Sie haben das Objekt gebeizt, nicht die Instanzmethode. Versuchen Sie, eine Instanzmethode direkt zu verwenden. –

+0

pickle die Instanz und dann Zugriff auf die Methode nach dem Entpacken. Das Auswählen einer Methode einer Instanz ist nicht sinnvoll, da sie auf der Instanz beruht. Wenn nicht, schreibe es als unabhängige Funktion. –