web-dev-qa-db-ja.com

__init__の外部で定義されたインスタンス属性attribute_name

次のように、複数の関数を呼び出せるようにしてクラスコンストラクターを分割しました。

class Wizard:
    def __init__(self, argv):
        self.parse_arguments(argv)
        self.wave_wand() # declaration omitted

    def parse_arguments(self, argv):
        if self.has_correct_argument_count(argv):
            self.name = argv[0]
            self.magic_ability = argv[1]
        else:
            raise InvalidArgumentsException() # declaration omitted

# ... irrelevant functions omitted

私のインタプリタは私のコードを喜んで実行しますが、Pylintは苦情を言っています

Instance attribute attribute_name defined outside __init__

現在、大まかなGoogle検索は実りありません。すべてのコンストラクターロジックを__init__に保持することは整理されていないように思われ、Pylint警告をオフにすることもハックのようです。

この問題を解決するa/the Pythonicの方法は何ですか?

128
Steven Liao

このメッセージの背後にある考え方は、読みやすさのためです。インスタンスが持つ可能性のあるすべての属性を見つけるには、__init__メソッドを読み取ります。

ただし、初期化を他のメソッドに分割することもできます。このような場合、属性を__init__内のNone(少しのドキュメント付き)に割り当てるだけで、サブ初期化メソッドを呼び出すことができます。

129
sthenault

parse_arguments()からTupleを返し、必要に応じて__init__内の属性に展開します。

また、exit(1)を使用する代わりに、例外を使用することをお勧めします。トレースバックを取得したり、コードを再利用したりできます。

class Wizard:
    def __init__(self, argv):
        self.name,self.magic_ability = self.parse_arguments(argv)

    def parse_arguments(self, argv):
        assert len(argv) == 2
        return argv[0],argv[1]
28
roippi

関数を介して設定する属性ごとに、initから関数を呼び出します。たとえば、属性ascii_txt ...を設定するには次のように動作します.

def __init__(self, raw_file=None, fingerprint=None):
    self.raw_file = raw_file
    self.ascii_txt = self.convert_resume_to_ascii()

def convert_resume_to_ascii(self):
    ret_val = self.raw_file.upper()
    return ret_val
0
Ben