Pregunta

No pude encontrar documentación sobre un equivalente del final de Java en Python, ¿existe tal cosa?

Estoy creando una instantánea de un objeto (usado para restauración si algo falla); una vez que se asigna esta variable de copia de seguridad, no se debe modificar, una buena característica final en Python sería buena para esto.

¿Fue útil?

Solución

Tener una variable en Java sea final básicamente significa que una vez que asigna una variable, no puede reasignar esa variable para que apunte a otro objeto. En realidad no significa que el objeto no pueda ser modificado. Por ejemplo, el siguiente código Java funciona perfectamente bien:

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

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

pero lo siguiente ni siquiera compilaría:

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

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

Entonces, tu pregunta es sobre si final existe en Python. No lo hace.

Sin embargo, Python tiene estructuras de datos inmutables. Por ejemplo, mientras puede mutar una lista , no puede mutar una tupla . Puede mutar un set pero no un frozenset , etc.

Mi consejo sería que no te preocupes por imponer la no mutación en el nivel del idioma y simplemente que te concentres en asegurarte de no escribir ningún código que mute estos objetos una vez que se hayan asignado.

Otros consejos

No hay un `` final '' equivalente en Python.

Pero, para crear campos de solo lectura de instancias de clase, puede usar propiedad función.

Editar : quizás quieras algo como esto:

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

        self.__dict__[attr] = value

Una variable de asignar una vez es un problema de diseño. Usted diseña su aplicación de manera que la variable se establezca una sola vez.

Sin embargo, si desea que su diseño se verifique en tiempo de ejecución, puede hacerlo con un envoltorio alrededor del objeto.

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

Eso es torpe, pero detectará problemas de diseño en tiempo de ejecución.

No hay tal cosa. En general, la actitud de Python es " si no quieres que se modifique, simplemente no lo modifiques " Es improbable que los clientes de una API se acerquen a sus internos no documentados de todos modos.

Supongo que podría solucionar este problema utilizando tuplas o tuplas con nombre para los bits relevantes de su modelo, que son inherentemente inmutables. Eso todavía no ayuda con ninguna parte de su modelo que tenga que ser modificable, por supuesto.

Python no tiene equivalente de " final " ;. No tiene " público " y " protegido " cualquiera de los dos, excepto por convención de nombres. No es que " esclavitud y disciplina " ;.

puede simular algo así a través del protocolo descriptor , ya que permite definir la lectura y la configuración de una variable de la forma que desee.

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/ define un Función de congelación, aunque no funciona perfectamente.

Sin embargo, consideraría simplemente dejarlo mutable.

Aunque esta es una pregunta antigua, pensé que agregaría otra opción potencial: también puede usar assert para verificar que una variable esté configurada para lo que originalmente pretendía que se configurara en: a Comprobación doble si lo desea. Aunque esto no es lo mismo que final en Java, se puede usar para crear un efecto similar:

PI = 3.14
radius = 3

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

Como se vio anteriormente, si PI no se configuró en 3.14 por algún motivo, se lanzará un AssertionError , por lo que se lanzará un El bloque try / except probablemente sería una adición inteligente. En cualquier caso, puede ser útil dependiendo de su situación.

De hecho, Python no tiene un tipo final, tiene tipos inmutables como tuplas, pero eso es otra cosa.

Algunas de las otras Respuestas aquí hacen que las clases estén llenas de pseudo variables finales y prefiero que mi clase tenga solo unos pocos tipos de Final, así que sugiero usar un descriptor para crear el tipo final:

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")

Si usa esta clase de esta manera:

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

Entonces no podrá establecer esa variable en ninguna instancia de esa clase. Desafortunadamente, como con la respuesta de WriteOnceReadWhenever, aún puede establecer la variable de clase.

job = SomeJob()
job.FAILED = "Error, this will trigger the ValueError"
SomeJob.FAILED = "However this still works and breaks the protection afterwards"
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top