java - estáticas - variable estática python
¿palabra clave `final` equivalente para variables en Python? (9)
No pude encontrar documentación sobre un equivalente de la final
de Java en Python, ¿existe tal cosa?
Estoy creando una instantánea de un objeto (utilizado para restauración si algo falla); una vez que esta variable de respaldo es asignada, no debe ser modificada, una característica final en Python sería agradable para esto.
Aunque esta es una vieja pregunta, pensé que agregaría otra opción potencial: también puedes utilizar assert
para verificar que una variable esté configurada en lo que originalmente pretendías que fuera: una doble comprobación, si así lo deseas. 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
por algún motivo no se configurara en 3.14
, se lanzaría un AssertionError
, por lo que un bloque try/except
sería probablemente una buena adición. De todos modos, puede ser útil dependiendo de su situación.
No existe tal cosa. En general, la actitud de Python es "si no quieres que esto se modifique, simplemente no lo modifiques". Es improbable que los clientes de una API simplemente hurguen alrededor de sus partes internas sin documentar de todos modos.
Podría, supongo, solucionar este problema utilizando tuplas o miniaturas con nombre para los bits relevantes de su modelo, que son intrínsecamente inmutables. Eso todavía no ayuda con ninguna parte de su modelo que deba ser mutable, por supuesto.
No hay equivalente "final" en Python.
Sin embargo, para crear campos de solo lectura de instancias de clase, puede usar la función de property .
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
Puedes simular algo así a través del protocolo descriptor , ya que permite definir la lectura y establecer una variable de la forma que desees.
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
Python de hecho no tiene un tipo final, tiene tipos inmutables como tuplas, pero eso es otra cosa.
Algunas de las otras respuestas aquí hacen clases llenas de variables pseudo finales y yo prefiero que mi clase tenga solo algunos tipos finales, 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 usas esta clase así:
class SomeJob:
FAILED = FinalProperty[str]("Failed")
Entonces no podrá establecer esa variable en ninguna instancia de esa clase. Desafortunadamente, como con la respuesta 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"
Python no tiene equivalente de "final". Tampoco tiene "público" y "protegido", excepto nombrando la convención. No es esa "esclavitud y disciplina".
Tener una variable en Java ser final
básicamente significa que una vez que se asigna a una variable, no se puede reasignar esa variable para apuntar 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 el siguiente ni siquiera compilará:
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 si la final
existe en Python. No es asi.
Sin embargo, Python tiene estructuras de datos inmutables. Por ejemplo, aunque puede mutar una list
, no puede mutar una tuple
. Puede mutar un set
pero no un conjunto de frozenset
, etc.
Mi consejo sería que simplemente no te preocupes por imponer la no mutación en el nivel del idioma y simplemente concéntrate en asegurarte de no escribir ningún código que mute estos objetos después de que se hayan asignado.
Una variable asignar una vez es un problema de diseño. Usted diseña su aplicación de forma que la variable se establezca una sola vez.
Sin embargo, si desea verificar su diseño en tiempo de ejecución, puede hacerlo con un contenedor 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.
http://code.activestate.com/recipes/576527/ define una función de congelación, aunque no funciona a la perfección.
Sin embargo, consideraría dejarlo mutable.