2017-10-21 2 views
-3

Angenommen, wir haben eine Funktion:In Python, wie macht man einen Eingabeparameter zu Funktion unveränderlich?

import copy 

def demo_function(list_in) 
    list_out = copy.deepcopy(list_in) 
    list_in.append("howdy") 
    return list_out 

Beachten Sie, dass wir list_in statt list_out anhängen. Allerdings sollte demo_function nicht eigentlich seine Eingabe ändern. Wir wollen dies durchsetzen. Ein Fehler sollte ausgelöst werden, wenn jemand versehentlich list_in irgendwo innerhalb des Körpers von demo_function ändert Wie können wir diese Art von Fehlerüberprüfung implementieren?

Das folgende ist mein bester Versuch, aber es funktioniert nicht. Die Zeichenfolge "howdy" wird immer noch an list_in angehängt;

Ich bedaure mit einer Liste, wie mein Beispiel: wird kein Fehler

class Frozen(object): 
    # The Frozen class was developed by ActiveState Software Inc. 
    def __init__(self, value): 
     self._value = value 

    def __getattribute__(self, name): 
     if name == '_value': return super(Frozen, self).__getattribute__(name) 
     v = getattr(self._value, name) 
     return v if hasattr(v, '__hash__') else Frozen(v) 

    def __setattr__(self, name, value): 
     if name == '_value': super(Frozen, self).__setattr__(name, value) 
     else: raise Exception("Can't modify frozen object {0}".format(self._value)) 

def const(some_function):  
    def wrapper(fargs,*args,**kwargs): 
     for f in fargs: 
      f = Frozen(f) 
      pass 
     for a in args: 
      a = Frozen(a) 
      pass 
     for k in kwargs: 
      k = Frozen(k) 
      pass 
     some_function(fargs, *args, **kwargs)  
    return wrapper 

@const 
def demo_function(list_in): 
    list_out = copy.deepcopy(list_in) 
    list_in.append("howdy") 
    return list_out 

lisandra = [1, 2, 3, 4, 5] 

modified_lisandra = demo_function(lisandra) 

print(lisandra) 

bearbeiten geworfen. Ich möchte wirklich eine allgemeine Lösung, die die Eingaben einer Funktion unveränderlich (const) machen würde, egal was ihre Datentypen sind. Es ist sehr einfach, eine Python-Liste in ein Tupel zu konvertieren. Was aber, wenn die Eingabe für die Funktion eine Instanz einer benutzerdefinierten Klasse ist? Sie wissen nicht, wie Sie es in ein Tupel umwandeln können. Selbst wenn Sie wissen, wie Sie das Objekt in ein Tupel konvertieren, möchten Sie nicht für jeden Datentyp in Ihrem Projekt eine andere Lösung schreiben. Wir wollen eine einzige Lösung, die die Werte der Eingänge einer Funktion einfriert, unabhängig vom Datentyp dieser Eingänge.

+0

ein Tupel verwenden? 'lisandra = (1, 2, 3, 4, 5)' – James

+0

Sie könnten stattdessen ein Tupel verwenden. –

+0

Warum möchten Sie, dass es unveränderlich ist? Was hoffst du zu gewinnen? –

Antwort

0

Man könnte immer so etwas wie dies versuchen ..

import copy 

def demo_function(list_in): 
    original = list_in[:] 
    list_out = copy.deepcopy(list_in) 
    list_in.append("howdy") 
    assert original == list_in 
    return list_out