7

インスタンスで値を取得する場合と取得しない場合がある変数があります。

class EC():
   __init__(self, a=False):
   ...
   if a: self.__var = ...

後で、インスタンスに__varが存在するかどうかを確認したいと思います。名前の先頭に__を追加すると、内部名が_EC__varに変更されるため、チェック コードが少し面倒になります。

if ''.join(['_',self.__class__.__name__,'__name']) in self.__dict__: ...

上記のコードは正常と見なされますか? そうでない場合、好ましい代替手段は何ですか?

私が考えることができる 1 つのオプションは、とにかく__varに何らかの値を与えることです。次に例を示します。

_no_value = object()
...
   def __init__(self, a):
      self.__var = _no_value
      ...
      if a: self.__var = ...

そのため、後で内部変数を混乱させる代わりに、__ varを_no_valueと比較できます。

4

4 に答える 4

11

hasattr(self, '_var') を使用して、存在するかどうかを確認します。None に設定されている場合もありますが、hasattr が存在すると言えば存在します。

例えば:

>>> class a():
...   def __init__(self):
...      self.a = 3
...      self._a_ = 4
...      self.__a__ = 'Fred'
...
>>> A=a()
>>> hasattr(a, 'a')
False
>>> hasattr(A, 'a')
True
>>> hasattr(A, '_a_')
True
>>> hasattr(A, '__a__')
True
>>> hasattr(A, '__b__')
False
>>>
于 2013-08-01T14:25:26.197 に答える
4

None クラスに設定するだけです:

 class EC():
    __var = None

    __init__(self, a=False):
        ...
        if a: self.__var = ...

をテストしif self.__var is not Noneます。

Noneが属性の有効な値である必要がある場合は、別のシングルトン センチネルを使用します。

_sentinel = object()

 class EC():
    __var = _sentinel

    __init__(self, a=False):
        ...
        if a: self.__var = ...

をテストしif self.__var is not _sentinelます。

このようにして、へのすべての参照__varがクラス名を含むように適切に書き換えられます。

もう 1 つの方法は、属性に二重下線を使用しないことです。サブクラスが誤って独自の属性でそれを上書きしない__varように、特定のクラスに名前空間を付けたい属性にのみ使用する必要があります。

つまり、アンダースコアが 2 つある名前は、それが何のためにあるのかを本当に理解し、実際に必要としない限り、使用しないでください。未知のサードパーティによる幅広い消費のためのフレームワークの一部ではないコードはありますか? 代わりに、単一のアンダースコアに固執してください。

于 2013-08-01T14:28:37.540 に答える