1

私は Python でクラスレベル変数のリスクをいじっていましたが、クラスレベル変数としてのリストのリスクは、タプル (空のタプルなど) で解決できると考えました。

取った:

class BaseClass(object):
    default_sth = []

    def foo(self):
       for sth in self.default_sth:
           pass

これは次の理由で危険です。

class SubClass(BaseClass):
    pass

a = SubClass()
a.default_sth.append(3)

print(BaseClass.default_sth) # [3]

None空のタプル ( ?) の代わりに使用するtuple()と、反復時に失敗するため、代わりに危険になる可能性があります。

不変性のため、これは良い選択肢だと思いますが、どこかでこれについて話している人を見たことがないと思います。この推論に欠陥があると思いますか? それはpythonicですか?

4

3 に答える 3

2

クラス変数とインスタンス変数を混​​同しています (初期化されたインスタンス変数がない場合、ルックアップでクラス変数が検出されるため、これは簡単です)。この場合、default_sthインスタンス変数のデフォルト値を持つことを意味するときに、それがクラス変数であると明示的に言いました。代わりにこれを使用してください:

class BaseClass(object):
    def __init__(self, sth=None):
        if sth is None:
            sth = []

    def foo(self):
       for sth in self.sth:
           pass

「ハードコーディングされた」デフォルトを持つことに少し躊躇するかもしれませんが、デフォルト値に別の名前を付けようとすることで冗長性を追加しているだけです。__init__メソッドにコメントを付けて文書化sthし、他の値が渡されない場合のデフォルト値とは何かを示します。正当な理由がない限り、デフォルト自体を構成可能にしようとしないでください。

不変性に関する限り、タプルのみが不変であり、それを参照する名前は不変です。誰かがあなたの元のコードを使って言うのを止めるものは何もありません

BaseClass.default_sth = []

default_sth最初にタプルを作成したにもかかわらず、開始した場所に戻っています。

于 2014-07-11T20:07:43.027 に答える
0

変更可能なデフォルト変数は、それ以外の点では非常に美しい Python でよく知られているおならです。

例えば

http://eli.thegreenplace.net/2009/01/16/python-insight-beware-of-mutable-default-values-for-arguments/

「最小の驚き」と変更可能なデフォルト引数

http://pythonconquerstheuniverse.wordpress.com/2012/02/15/mutable-default-arguments/

ソリューションには以下が含まれます

  • すべてを初期化します__init__- 本当にグローバル変数を意味する場合を除き、クラスレベルの変数を使用しないでください

  • None初めてアクセスしたときに渡してリストに変換する

于 2014-07-11T19:40:31.987 に答える