2012-06-07 49 views
4

我的程序中有幾個對象每個都有大約10-15個屬性。這些屬性在程序中的不同階段被設置在代碼的不同位置。因爲將它們設置在對象上而不在Python中的類中定義它們是絕對好的,所以在我的程序中沒有關於使用哪些屬性的良好權威列表。如何定義Python對象的默認屬性列表?

我想類似如下:

class MyObject(object): 
    attr1 
    attr2 

我已經看了內置property(),但它至少6條線的每個屬性代碼。有沒有簡單的方法來定義默認屬性的列表,而無需在Python中進行初始化?

UPDATE:我忘了提及,大多數值沒有明智的默認值,並且在使用之前實際上等於None

+0

你想要那些沒有添加默認值'None'的值嗎?不知道如何更新信息... – martineau

+0

我真的不知道什麼是最pythonic的方式,我只是知道,我不能給所有的屬性值創建對象。 –

+0

通常它們都是在'__init __()'方法中定義的,即使只是將它們設置爲'0','None'或''''作爲將它們全部記錄下來的方式。另一方面,除非對象處於某種特定狀態,否則完全可以不定義一個對象,但其他對象可能難以理解。 – martineau

回答

5

是否這樣?

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的例子。

+0

看到我上面的更新,我沒有所有屬性的默認值。 –

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)) 

...在這種情況下,如果識別的對象屬性尚未設置,則會返回默認值。

+0

你的更新是一個有趣的想法 - 有點像「虛擬屬性」。然而,我會有點小心這樣做,因爲潛在的問題可能是,如果默認屬性具有可變值(通過一個實例更改)(如附加到列表),則該更改將顯示在所有其他現有實例以及隨後創建的新實例。另一方面,也許這是一個「功能」,雖然它可能違背最不讓人意外的原則...... – martineau

0

如果您希望可以使用默認值創建類屬性。如果一個類可以有許多屬性,但其中許多屬性通常未設置,或者如果實例已序列化,則可以確保只對非默認屬性進行序列化/反序列化,而忽略具有默認屬性的屬性值。

例如

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

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

現在,任何MyObject實例都有attr1attr2屬性它們是否被明確設置。請注意,如果你想讓一個默認值成爲一個序列,你應該確保使用一個元組,以便它不會意外發生變異。

5

我想休·博思韋爾是在正確的軌道上,但它可以更簡明地完成:

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} 
+0

非常棒!我忘了自己.__ dict__ - 這絕對是一個更簡潔的方式。 –

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) 
相關問題