6

プログラムには、それぞれ約10〜15個の属性を持つオブジェクトがいくつかあります。これらの属性は、プログラムのさまざまな段階でコードのさまざまな場所に設定されます。Pythonのクラスで定義せずにオブジェクトに設定することは絶対に問題ないため、私のプログラムには、どの属性が使用されているかについての適切な信頼できるリストがありません。

次のようなものが欲しいのですが。

class MyObject(object):
    attr1
    attr2

ビルトインを見てきましたが、property()プロパティごとに少なくとも6行のコードがあります。Pythonで初期化せずにデフォルト属性のリストを定義する簡単な方法はありますか?

更新:言及するのを忘れました。ほとんどの値には適切なデフォルトがなく、None使用前と実質的に同じになります。

4

5 に答える 5

9

Hugh Bothwellは正しい方向に進んでいると思いますが、もっと簡潔に行うことができます。

class MyClass(object):
    _defaults = "attr1", "attr2", "attr3"
    _default_value = None

    def __init__(self, **kwargs):
        self.__dict__.update(dict.fromkeys(self._defaults, self._default_value))
        self.__dict__.update(kwargs)


my_object = MyClass(attr3='overridden', attr4='added')

print(vars(my_object))

出力:

{'attr4': 'added', 'attr2': None, 'attr3': 'overridden', 'attr1': None}

クラス属性(実行時に変更される可能性があります)を_defaults作成しました。(ただし、変更可能なデフォルト値_default_valueを提供するには、作成されたすべてのインスタンスで共有されないようにするための追加のコードが必要になる可能性があります。)

これを拡張して、デフォルト属性ごとに異なる(不変の)デフォルト値を定義できるようにするのは簡単です。

class MyClass(object):
    _defaults = {
        "attr1": None,
        "attr2": 0,
        "attr3": ""
    }

    def __init__(self, **kwargs):
        self.__dict__.update(self._defaults)
        self.__dict__.update(kwargs)


my_object = MyClass(attr3='overridden', attr4='added')

print(vars(my_object))

出力:

{'attr4': 'added', 'attr2': 0, 'attr3': 'overridden', 'attr1': None}
于 2012-06-07T12:41:08.880 に答える
6

このような?

class MyObject(object):
    def __init__(self, attr1 = default1, attr2 = default2):
        self.attr1 = attr1
        self.attr2 = attr2

MyObject属性を指定して、または指定せずにインスタンス化できます

myObject1 = MyObject() # gets default values 
myObject2 = MyObject(foo, bar) # overrides defaults

kwargs属性の数が可変の場合は、キーワード引数()を使用することもできます。例については、ここを参照してください。

于 2012-06-07T12:05:28.553 に答える
4

渡すプロパティが多数ある場合は、次のように読みやすくなります。

class Myclass(object):
    def __init__(self, **kwargs):
        defaults = {
            "attr1": None,
            "attr2": 0,
            "attr3": ""
        }
        defaults.update(kwargs)
        for attr,value in defaults.iteritems():
            self.__setattr__(attr, value)

編集: @martineauと@kosiiの提案を見て、ここに別の可能性があります:

class MyClass(object):
    defaults = {
        "attr1": None,
        "attr2": 0,
        "attr3": ""
    }

    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

    def __getattr__(self, key):
        try:
            # return a default value
            return MyClass.defaults[key]
        except KeyError:
            raise AttributeError("don't recognize .{}".format(key))

...この場合、認識されたオブジェクト属性は、実際にまだ設定されていない場合、デフォルト値を返します。

于 2012-06-07T12:26:54.177 に答える
1

ちょっと遊んでみ__getattr__ませんか?

class A(object):
    def __init__(self, special_attrs=[]):
        self.__dict__['_special_attrs_dict'] = dict.fromkeys(special_attrs)

    def __getattr__(self, key):
        if key in self._special_attrs_dict:
            return self._special_attrs_dict[key]
        raise AttributeError('')

    def __setattr__(self, key, value):
        if key in self._special_attrs_dict:
            self._special_attrs_dict[key] = value
        else:
            super(A, self).__setattr__(key, value)
于 2012-06-07T13:21:49.623 に答える
0

必要に応じて、デフォルト値でクラス属性を作成できます。これは、クラスに多くの属性を含めることができるが、それらの多くが未設定のままになっている場合や、インスタンスがシリアル化されている場合は、デフォルト以外の属性のみをシリアル化/逆シリアル化し、デフォルトの属性は無視する場合に特に便利です。値。

例えば

class MyObject(object):
    attr1 = 42
    attr2 = ()

instance = MyObject()
for x in instance.attr2:
    print(x)

これで、明示的に設定されているかどうかに関係なく、すべてのMyObjectインスタンスに属性がattr1あります。attr2デフォルト値をシーケンスにしたい場合は、誤って変更されないように、必ずタプルを使用する必要があることに注意してください。

于 2012-06-07T12:35:41.817 に答える