Java `Python中变量的final`关键字等价物?

Java `Python中变量的final`关键字等价物?,java,python,keyword,final,Java,Python,Keyword,Final,我在Python中找不到与Java的final相当的文档,有这样的东西吗 我正在创建一个对象的快照(如果出现任何故障,则用于恢复);一旦分配了这个备份变量,就不应该对它进行修改——Python中类似于final的特性就很好了。Python没有“final”的等价物。它也没有“public”和“protected”,除了命名约定之外。这并不是“束缚和约束”。没有这样的东西。一般来说,Python的态度是“如果你不想修改它,就不要修改它”。API的客户端无论如何都不可能只是浏览您未记录的内部构件 我

我在Python中找不到与Java的
final
相当的文档,有这样的东西吗


我正在创建一个对象的快照(如果出现任何故障,则用于恢复);一旦分配了这个备份变量,就不应该对它进行修改——Python中类似于final的特性就很好了。

Python没有“final”的等价物。它也没有“public”和“protected”,除了命名约定之外。这并不是“束缚和约束”。

没有这样的东西。一般来说,Python的态度是“如果你不想修改它,就不要修改它”。API的客户端无论如何都不可能只是浏览您未记录的内部构件

我想,您可以通过对模型的相关部分使用元组或命名元组来解决这一问题,它们本质上是不可变的。当然,这对模型中必须可变的任何部分都没有帮助。

定义了一个冻结函数,尽管它不能完美地工作


我会考虑让它变为可变。

< P>在Python中没有<代码>最终< /C> >等效。

但是,要创建类实例的只读字段,可以使用函数

编辑:也许你想要这样的东西:

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

        self.__dict__[attr] = value

在Java中使用变量be
final
基本上意味着一旦分配给变量,就不能重新分配该变量以指向另一个对象。这实际上并不意味着对象不能被修改。例如,以下Java代码工作得非常好:

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

public void addMessage()
{
    messages.add("Hello World!");  // this mutates the messages list
}
public final List messages=new LinkedList();
public void addMessage()
{
messages.add(“Hello World!”);//这会改变消息列表
}
但以下内容甚至无法编译:

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

public void changeMessages()
{
    messages = new ArrayList<String>();  // can't change a final variable
}
public final List messages=new LinkedList();
公共消息()
{
messages=new ArrayList();//无法更改最终变量
}
因此,您的问题是Python中是否存在
final
。事实并非如此

然而,Python确实有不可变的数据结构。例如,虽然可以变异
列表
,但不能变异
元组
。您可以变异
集合
,但不能变异
冻结集合
,等等


我的建议是,不要担心在语言级别强制执行非变异,只需专注于确保您不会编写任何代码,在这些对象被赋值后对其进行变异。

赋值一次变量是一个设计问题。在设计应用程序时,变量只能设置一次

但是,如果希望对设计进行运行时检查,可以使用对象周围的包装器来完成

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

这很笨拙,但它会在运行时检测设计问题。

您可以通过模拟类似的内容,因为它允许以您希望的方式定义读取和设置变量

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

虽然这是一个老问题,但我想我会添加另一个潜在选项:您还可以使用
assert
验证变量是否设置为您最初希望设置的值–如果愿意,请进行双重检查。虽然这与Java中的
final
不同,但它可以用于创建类似的效果:

PI = 3.14
radius = 3

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

如上所述,如果由于某种原因,
PI
未设置为
3.14
,则会抛出一个
AssertionError
,因此,
try/except
块可能是明智的添加。无论如何,它可能会根据您的情况派上用场。

Python确实没有最终类型,它确实有元组之类的不可变类型,但这是另外一回事

这里的一些其他答案使类充满伪final变量,我更喜欢我的类只有几个final类型,因此我建议使用描述符创建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")
如果您这样使用此类:

class SomeJob:
    FAILED = FinalProperty[str]("Failed")
那么您将无法在该类的任何实例中设置该变量。 不幸的是,与WriteOnCeradAnwhere答案一样,您仍然可以设置类变量

job = SomeJob()
job.FAILED = "Error, this will trigger the ValueError"
SomeJob.FAILED = "However this still works and breaks the protection afterwards"
到2019年和2019年,Python有一个
Final
类型。在Python3.8发布之前,它不会在标准库中可用,但在此之前,您可以通过库使用它。虽然Python仍然是一种动态类型化语言,但它不能在Java中工作,因为
final
。但是,如果您将它与静态类型检查器一起使用,它将给您带来非常相似的好处

还有一个
final
decorator,可用于将类方法标记为final并防止被重写。同样,这只在“编译时”进行检查,因此您需要在工作流中包含一个静态类型检查器。

(via)添加
Final
变量、函数、方法和类。以下是一些使用方法:

@final
装饰器(类、方法)

从输入import final开始
@决赛
类库:
#无法从基继承
类库:
@决赛
def foo(self):
#无法在子类中重写foo
最终版
注释

从输入import Final开始
PI:Final[float]=3.14159#无法将PI设置为其他值
KM_IN_MILES:Final=0.621371#类型注释是可选的
Foo类:
定义初始化(自):
self.bar:Final=“baz”#仅允许在u init中使用最终实例属性__

请注意,与其他类型提示一样,这些提示并不阻止您重写类型,但它们确实有助于linters或IDEs警告您错误的类型用法。

许多其他类也是不可变的:string、int、long、float。可能与total重复。。缺乏不变性是灾难性的。。证明Python不适用于大规模多线程应用程序。@ApurvaSingh虽然我同意Python不适用于这一点,但标准库中有元组和冻结集,它是一种可变映射的实现,可以