Frage

ich keine Dokumentation auf ein Äquivalent von Java final in Python finden konnten, gibt es so etwas?

Ich erstelle eine Momentaufnahme eines Objekts (verwendet für die Wiederherstellung, wenn etwas nicht); sobald diese Backup-Variablen zugewiesen werden, nicht geändert werden soll -. eine endgültige ähnliche Funktion in Python wäre dies schön

War es hilfreich?

Lösung

Nachdem eine Variable in Java im Grunde bedeutet final wird, dass, wenn Sie ein Variablen zuweisen, können Sie nicht die Variable neu zuweisen zu einem anderen Objekt zu zeigen. Es bedeutet eigentlich nicht, dass das Objekt nicht geändert werden kann. Zum Beispiel arbeitet der folgende Java-Code sehr gut:

public final List<String> messages = new LinkedList<String>();

public void addMessage()
{
    messages.add("Hello World!");  // this mutates the messages list
}

aber die folgenden würde nicht einmal kompilieren:

public final List<String> messages = new LinkedList<String>();

public void changeMessages()
{
    messages = new ArrayList<String>();  // can't change a final variable
}

So Ihre Frage ist, ob final in Python existiert. Es funktioniert nicht.

Allerdings ist Python unveränderliche Datenstrukturen hat. Zum Beispiel, während Sie ein list mutieren können, können Sie keinen tuple mutieren. Sie können eine set mutieren aber kein frozenset, etc.

Mein Rat wäre, nur keine Sorgen um die Durchsetzung nicht-Mutation an dem Sprachniveau und einfach dafür sorgen, dass konzentrieren, dass Sie keinen Code schreiben Sie nicht, die diese Objekte mutieren, nachdem sie zugeordnet sind.

Andere Tipps

Es gibt keine `` final '' äquivalent in Python.

Aber erstellen schreibgeschützten Felder von Klasseninstanzen, können Sie die verwenden Eigenschaft Funktion.

Bearbeiten : Vielleicht wollen Sie etwas wie folgt aus:

class WriteOnceReadWhenever:
    def __setattr__(self, attr, value):
        if hasattr(self, attr):
            raise Exception("Attempting to alter read-only value")

        self.__dict__[attr] = value

Ein assign-once Variable ein Design-Problem ist. Sie gestalten Ihre Anwendung in einer Art und Weise, dass die Variable einmal gesetzt ist und nur einmal.

Wenn Sie jedoch zur Laufzeit wollen Ihr Design überprüfen, können Sie es mit einem Wrapper um das Objekt tun.

class OnePingOnlyPleaseVassily( object ):
    def __init__( self ):
        self.value= None
    def set( self, value ):
        if self.value is not None:
            raise Exception( "Already set.")
        self.value= value

someStateMemo= OnePingOnlyPleaseVassily()
someStateMemo.set( aValue ) # works
someStateMemo.set( aValue ) # fails

Das ist klobig, aber es wird Design-Probleme während der Laufzeit erkennen.

Es gibt nicht so etwas. Im Allgemeinen ist die Python Haltung „wenn Sie diese veränderte nicht wollen, es einfach nicht ändern“. Kunden einer API sind unwahrscheinlich, einfach mal so um Ihre undokumentierte Interna stecken.

Sie könnten, nehme ich an, um um dieses von Tupeln oder namedtuples für die entsprechenden Bits des Modells, die sind von Natur aus unveränderlich verwenden. Das immer noch nicht mit irgendeinem Teil Ihres Modell helfen, die wandelbar natürlich sein muss.

Python hat keine Entsprechung von "final". Es muss nicht „öffentlich“ und „geschützt“ entweder, mit Ausnahme von Namenskonvention. Es ist nicht so „Bondage und Disziplin“.

Sie können so etwas wie die durch das Descriptor-Protokoll , da es erlaubt eine variable, wie Sie wollen.

class Foo(object):

  @property
  def myvar(self):
     # return value here

  @myvar.setter
  def myvar(self, newvalue):
     # do nothing if some condition is met

a = Foo()
print a.myvar
a.myvar = 5 # does nothing if you don't want to

http://code.activestate.com/recipes/576527/ definiert ein Freeze-Funktion, obwohl es nicht perfekt funktioniert.

Ich würde nur verlassen sie wandelbar though.

Obwohl dies eine alte Frage ist, dachte ich, ich noch eine weitere mögliche Option hinzufügen würde: Sie auch assert eine Variable überprüfen können eingestellt ist, was Sie ursprünglich beabsichtigt es zu setzen - eine doppelte Überprüfung, wenn man so will. Obwohl dies nicht die gleichen wie final in Java ist, kann es verwendet werden, um einen ähnlichen Effekt zu erzeugen:

PI = 3.14
radius = 3

try:
    assert PI == 3.14
    print PI * radius**2
except AssertionError:
    print "Yikes."

Wie oben zu sehen ist, wenn PI aus irgendeinem Grunde sind nicht 3.14 gesetzt, wäre ein AssertionError geworfen werden, so dass ein try/except Block wäre wahrscheinlich eine sinnvolle Ergänzung sein. Unabhängig davon, kann es nützlich sein, je nach Ihrer Situation.

Python ist in der Tat nicht um eine endgültige Art haben, tut es unveränderliche Typen haben wie Tupeln, aber das ist etwas anderes.

Einige der anderen Antworten hier machen Klassen voller Pseudo endgültigen Variablen und ich ziehe meine Klasse nur ein paar Abschlusstypen haben, so schlage ich vor, einen Descriptor unter Verwendung der letzte Art zu erstellen:

from typing import TypeVar, Generic, Type

T = TypeVar('T')

class FinalProperty(Generic[T]):
    def __init__(self, value: T):
        self.__value = value
    def __get__(self, instance: Type, owner) -> T:
        return self.__value
    def __set__(self, instance: Type, value: T) -> None:
        raise ValueError("Final types can't be set")

Wenn Sie diese Klasse wie folgt:

class SomeJob:
    FAILED = FinalProperty[str]("Failed")

Dann werden Sie nicht in der Lage sein, diese Variable dieser Klasse in jedem Fall einzustellen. Leider wie bei der WriteOnceReadWhenever Antwort können Sie immer noch die Klassenvariable gesetzt.

job = SomeJob()
job.FAILED = "Error, this will trigger the ValueError"
SomeJob.FAILED = "However this still works and breaks the protection afterwards"
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top