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