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您可以在指定或不指定属性的情况下实例化 a

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实例都具有attr1attr2属性,无论它们是否被显式设置。请注意,如果您希望默认值是一个序列,您应该确保使用一个元组,这样它就不会被意外改变。

于 2012-06-07T12:35:41.817 回答