私はusage of slotsの主な答えを読んで、どのようにそしてどこで__slots__
を使うべきかという考えを得ました。属性の初期化で `__slots__`を使うには?
さて、私は以下のように似ているのPython 3へのPython 2からコードを移植しています:
class B(object):
__slots__ = ('_fields')
_fields = set()
しかし、Pythonの2に細かい仕事をしながら、これはPythonの3エラーを与えている:
をValueError: '_fields' in __slots__ conflicts with class variable
。
は私が
class B(object):
__slots__ = ('_fields')
def __init__(self):
_fields = set()
にコードを変更し、それが正常に動作します。私の質問は、それは正しい変更ですか?
私は元のコードから得たので、__dict__
をメモリや高速アクセスなどの理由で使用しないでください。同時に、属性のタイプをset()として指定しようとしています。 。上記の変更は、それを言う正しい方法であるか、またはいくつかの副作用を有する可能性があります。
さらなる実験:
import pdb
class A(object):
a = set()
'''
class B(object):
__slots__ = ('a')
a = set()
'''
class C(object):
__slots__ = ('a')
def __init__(self):
a = set()
class D(object):
def __init__(self):
__slots__ = ('a')
a = set()
if __name__ == '__main__':
#pdb.set_trace()
x = A(); print(dir(x))
#y = B()
z = C(); print(dir(z))
z1 = D(); print(dir(z1))
、それが出力以下与えた: 私は(Pythonの3の)以下のバリエーションで、さらに実験を行いました。
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a']
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', 'a']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
我々は、Cのオブジェクト、すなわち無__dict__
のみ__slots__
正しいフットプリントを示すことがわかります。理想的には私たちが望むものではありませんか? __weakref__
の説明も参考になります。
また、Python 2では、BオブジェクトとCオブジェクトの両方が同じフットプリントを示します。それに基づいて、Python 2とPython 3の両方でコンパイルしているので、Cを適切な方法で置くべきです。
ありがとうございました。しかし、代わりに '__init__'の中で次のように言っていましたか? ' self._fields = _fieldsがない場合はelse '' boolean context 'の '_fields'をチェックしていなければ' – ViFI
'を設定します(http:// stackoverflow .com/a/1452500/1431750)。 '_fields'が' None'の場合、その式は 'True'と評価され、' self._fields = set() 'という行が実行されます。これは、 '_fieldsがNoneの場合は、:self._fields = set()'とすることもできます。 Btw、あなたのコメントの例では、 'not None'は常にTrueです。もし_fieldsがNone else set() 'ならば' self._fields = _fields '、それ以外の場合は 'self._fields = _fields _fields else set()'のように置くことができます。 _Caveat:_空の 'set()'はFalseに評価されますので、適切なチェックを使用してください... – aneroid
_Caveat:_空の 'set()'はFalseに評価されますので、 'set() 「なし」はありません。また、関数またはメソッドを[デフォルトの引数値として変更可能な型]で初期化しないでください(http://stackoverflow.com/q/1132941/1431750)。 'set'、' dict'、 'list'などのようなものです。[ここの別の例](http://docs.python-guide.org/en/latest/writing/gotchas/#mutable-default-arguments)。 – aneroid