76

finalPythonでJavaに相当するドキュメントを見つけることができませんでしたが、そのようなものはありますか?

オブジェクトのスナップショットを作成しています(何かが失敗した場合の復元に使用されます)。このバックアップ変数が割り当てられたら、変更しないでください。Pythonのfinalのような機能がこれに適しています。

4

11 に答える 11

71

finalPythonには同等 のものはありません。

ただし、クラスインスタンスの読み取り専用フィールドを作成するには、プロパティ関数を使用できます。

編集:おそらくあなたはこのようなものが欲しいです:

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

        self.__dict__[attr] = value
于 2009-04-29T14:30:34.640 に答える
71

Javaに変数がある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<String> messages = new LinkedList<String>();

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

だからあなたの質問はfinalPythonに存在するかどうかについてです。そうではありません。

ただし、Pythonには不変のデータ構造があります。たとえば、を変更することはできますがlist、を変更することはできませんtuple。変更することはできますが、変更することはできsetませんfrozenset

私のアドバイスは、言語レベルで非変更を強制することを心配せず、割り当てられた後にこれらのオブジェクトを変更するコードを記述しないようにすることに集中することです。

于 2009-04-29T14:32:44.383 に答える
50

Python 3.8 ( PEP 591経由)はFinal、変数、関数、メソッド、およびクラスを追加します。これを使用するいくつかの方法があります:

@finalデコレータ(クラス、メソッド)

from typing import final

@final
class Base:
    # Cannot inherit from Base

class Base:
    @final
    def foo(self):
        # Cannot override foo in subclass

Final注釈

from typing import Final

PI: Final[float] = 3.14159     # Cannot set PI to another value
KM_IN_MILES: Final = 0.621371  # Type annotation is optional

class Foo:
    def __init__(self):
        self.bar: Final = "baz"   # Final instance attributes only allowed in __init__

他のタイピングのヒントと同様に、これらはタイプのオーバーライドを妨げるものではありませんが、リンターやIDEがタイプの誤った使用法について警告するのに役立ちます。

于 2019-10-14T22:20:11.027 に答える
10

一度割り当て変数は設計上の問題です。変数が一度だけ設定されるようにアプリケーションを設計します。

ただし、デザインの実行時チェックが必要な場合は、オブジェクトのラッパーを使用してチェックできます。

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

これは不格好ですが、実行時に設計上の問題を検出します。

于 2009-04-29T14:41:33.397 に答える
7

そのような事はありません。一般に、Pythonの態度は、「これを変更したくない場合は、変更しないでください」です。APIのクライアントは、とにかく文書化されていない内部をただ突っ込む可能性は低いです。

本質的に不変であるモデルの関連ビットにタプルまたは名前付きタプルを使用することで、これを回避できると思います。もちろん、それでもモデルの変更可能である必要のある部分には役立ちません。

于 2009-04-29T14:29:04.690 に答える
6

Pythonには「final」に相当するものはありません。命名規則を除いて、「public」と「protected」もありません。それは「束縛と規律」ではありません。

于 2009-04-29T14:28:29.950 に答える
6

記述子プロトコルを介してそのようなものをシミュレートできます。これにより、変数の読み取りと設定を希望どおりに定義できます。

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
于 2009-06-30T10:41:27.897 に答える
6

2019年およびPEP591の時点で、PythonにはFinalタイプがあります。Python 3.8がリリースされるまで標準ライブラリでは利用できませんが、それまでは、typeing-extensionsライブラリを介して使用できます。finalPythonはまだ動的に型付けされた言語であるため、Javaでは機能しません。しかし、 mypyのような静的タイプチェッカーと一緒に使用すると、非常によく似た利点が得られます。

finalクラスメソッドをfinalとしてマークし、オーバーライドされないようにするために適用できるデコレータもあります。繰り返しますが、これは「コンパイル時」にのみチェックされるため、ワークフローに静的型チェッカーを含める必要があります。

于 2019-09-03T14:59:31.853 に答える
3

http://code.activestate.com/recipes/576527/はフリーズ機能を定義していますが、完全には機能しません。

ただし、変更可能のままにしておくことを検討します。

于 2009-04-29T14:29:05.500 に答える
1

Pythonには確かに最終的な型がなく、タプルなどの不変の型がありますが、それは別のものです。

ここにある他の回答のいくつかは、クラスを疑似最終変数でいっぱいにします。クラスにはいくつかの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")

そうすると、そのクラスのどのインスタンスでもその変数を設定できなくなります。残念ながら、WriteOnceReadWheneverの回答と同様に、クラス変数を設定できます。

job = SomeJob()
job.FAILED = "Error, this will trigger the ValueError"
SomeJob.FAILED = "However this still works and breaks the protection afterwards"
于 2018-08-10T12:20:36.873 に答える
0

これは古い質問ですが、さらに別の潜在的なオプションを追加することassertにしました。変数が本来の設定に設定されていることを確認するために使用することもできます。必要に応じて再確認します。これはJavaの場合と同じではありませんがfinal、同様の効果を作成するために使用できます。

PI = 3.14
radius = 3

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

上記のように、PI何らかの理由でに設定されていない場合は3.14AssertionErrorがスローされるため、try/exceptブロックはおそらく賢明な追加になります。とにかく、状況によっては重宝するかもしれません。

于 2013-09-07T05:29:23.090 に答える