Pergunta

Não consegui encontrar documentação equivalente ao Java final em Python, existe tal coisa?

Estou criando um instantâneo de um objeto (usado para restauração se algo falhar);uma vez atribuída esta variável de backup, ela não deve ser modificada - um recurso semelhante ao final em Python seria bom para isso.

Foi útil?

Solução

Ter uma variável em java ser final Basicamente, significa que, depois de atribuir a uma variável, você não pode reatribuir essa variável para apontar para outro objeto. Na verdade, não significa que o objeto não pode ser modificado. Por exemplo, o código Java a seguir funciona perfeitamente bem:

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

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

Mas o seguinte nem sequer compilaria:

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

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

Portanto, sua pergunta é sobre se final Existe em Python. Isso não.

No entanto, o Python possui estruturas de dados imutáveis. Por exemplo, enquanto você pode sofrer muta list, você não pode sofrer muta tuple. Você pode mudar um set mas não um frozenset, etc.

Meu conselho seria simplesmente não se preocupar em aplicar a não mutação no nível do idioma e simplesmente se concentrar em garantir que você não escreva nenhum código que se afaste desses objetos após o designado.

Outras dicas

Não existe `` final '' equivalente em Python.

Mas, para criar campos somente leitura de instâncias de classe, você pode usar o propriedade função.

Editar: Talvez você queira algo assim:

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

        self.__dict__[attr] = value

Uma variável de atribuição-ONCE é um problema de design. Você cria seu aplicativo de uma maneira que a variável seja definida de uma vez e uma vez.

No entanto, se você deseja verificar o seu design em tempo de execução, poderá fazê-lo com um invólucro ao redor do 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

Isso é desajeitado, mas detectará problemas de design no tempo de execução.

Não existe tal coisa. Em geral, a atitude do Python é "se você não deseja isso modificado, apenas não o modifique". É improvável que clientes de uma API cutucam seus internos indocumentados.

Suponho que você possa contornar isso usando tuplas ou chamados para os bits relevantes do seu modelo, que são inerentemente imutáveis. Isso ainda não ajuda em nenhuma parte do seu modelo que deve ser mutável, é claro.

Python não tem equivalente a "Final". Também não tem "público" e "protegido", exceto por nomear a Convenção. Não é esse "escravidão e disciplina".

você pode simular algo assim através do Protocolo do descritor, pois permite definir a leitura e a definição de uma variável da maneira que você deseja.

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 uma função de congelamento, embora não funcione perfeitamente.

Eu consideraria apenas deixá -lo mutável.

Embora essa seja uma pergunta antiga, imaginei que acrescentaria mais uma opção potencial: você também pode usar assert Para verificar uma variável, está definido como o que você pretendia originalmente definir - uma verificação dupla, se você quiser. Embora isso não seja o mesmo que final Em Java, ele pode ser usado para criar um efeito semelhante:

PI = 3.14
radius = 3

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

Como visto acima, se PI por algum motivo não foram definidos para 3.14, um AssertionError seria jogado, então um try/except Block provavelmente seria uma adição sábia. Independentemente disso, pode ser útil, dependendo da sua situação.

Na verdade, o Python não possui um tipo final, ele possui tipos imutáveis, como tuplas, mas isso é outra coisa.

Algumas das outras respostas aqui tornam as classes cheias de variáveis ​​​​pseudofinais e eu prefiro que minha classe tenha apenas alguns tipos Finais, então sugiro usar um descritor para criar o 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")

Se você usar esta classe assim:

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

Então você não poderá definir essa variável em nenhuma instância dessa classe.Infelizmente, como acontece com a resposta WriteOnceReadWhenever, você ainda pode definir a variável de classe.

job = SomeJob()
job.FAILED = "Error, this will trigger the ValueError"
SomeJob.FAILED = "However this still works and breaks the protection afterwards"
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top