如何为类的实例定义默认属性列表?

时间:2012-06-07 12:04:15

标签: python properties attributes

我的程序中有一些对象,每个对象大约有10-15个属性。这些属性在程序的各个阶段设置在代码中的不同位置。因为在没有在Python类中定义对象的情况下将它们设置在对象上是绝对正确的,所以在我的程序中没有使用哪些属性的良好权威列表。

我想要以下内容:

class MyObject(object):
    attr1
    attr2

我查看了内置的property(),但每个属性至少有6行代码。有没有一种简单的方法来定义默认属性列表而无需在Python中初始化它们?

更新:我忘了提及,大多数值都没有合理的默认值,并且在使用之前实际上等于None

5 个答案:

答案 0 :(得分:8)

我认为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}

答案 1 :(得分: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),有关示例,请参阅here

答案 2 :(得分: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))

...在这种情况下,如果尚未实际设置,则识别的对象属性将返回默认值。

答案 3 :(得分: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)

答案 4 :(得分:0)

如果需要,可以使用默认值创建类属性。如果一个类可以有许多属性但是很多属性通常未设置,或者如果实例是序列化的,那么这可以特别有用,您可以确保只序列化/反序列化非默认属性并忽略具有默认属性的属性值。

e.g。

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

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

现在,任何MyObject实例都具有attr1attr2属性,无论它们是否已明确设置。请注意,如果您希望默认值为序列,则应确保使用元组,以便不会意外地进行变异。