2014-04-03 159 views
0

什麼樣的信息應該被設置爲我的課程的屬性的最蟒蛇方式是什麼?設置正確類型的類屬性

例如,我有一個名爲Human的類,類的屬性接受變量內的特定數據。

  • 頭髮必須是黑色,金色或大膽,
  • 年齡不得高於110,
  • 的腿和手必須是整數。
  • 名稱必須是一個字符串,等等

什麼是實現這一目標的最佳途徑?

class Human: 
    def __init__(self,name,legs,hands,age): 
     self.name = name #must be a string 
     self.legs = legs #must not be more than 2 
     self.hands = hands #same goes as legs above 
     self.age = age #must not be above 110 
     self.hair = hair #must be among hair_list = ['black','blonde','bold'] 
+0

每個屬性的'if'語句.. – msvalkon

+2

約一半時間,類型檢查/驗證是反模式。有一個原因是Python是動態輸入的。你確定你確實需要打字檢查嗎? –

+2

fyi ... [最早記錄的年齡記錄是122](http://en.wikipedia.org/wiki/Oldest_people#Ten_verified_oldest_women_ever)。 –

回答

2

處理託管屬性的一種方法是使用descriptors。例如:

class Name(object): 
    def __get__(self, instance, owner): 
     return self._name 

    def __set__(self, instance, name): 
     if not isinstance(name, basestring): 
      raise ValueError('Name must be a string') 
     self._name = name 


class Human(object): 
    name = Name() 

    def __init__(self, name): 
     self.name = name 

演示:

>>> h = Human(10) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "test.py", line 15, in __init__ 
    self.name = name 
    File "test.py", line 7, in __set__ 
    raise ValueError('Name must be a string') 
ValueError: Name must be a string 
>>> h = Human('test') 
>>> h.name 
'test' 

另見:Introduction to Python descriptors

0

我不認爲有一個更好的辦法不是要明確你的意圖,雖然也許你可以相信任何人創建Human -object會明白,你不能500多年的歷史。

我相信最pythonic的方式是raise一個有意義的異常,只要其中一個屬性不驗證。我還使用默認參數,使您不必從頭再來類型最常見的用例..

class Human: 
    def __init__(self, name, legs=2, hands=2, age=0, hair='blonde'): 
     if not isinstance(name, str): 
      raise TypeError("Name must be a string") 
     self.name = name 

     if legs > 2: 
      raise ValueError("More than 2 legs") 
     self.legs = legs 

     if hands > 2: 
      raise ValueError("More than 2 hands") 
     self.hands = hands 

     if age > 110: 
      raise ValueError("What, are you immortal?!") 
     self.age = age 

     if hair not in ['black', 'blonde', 'bold']: 
      raise ValueError("I'm sorry your hair color is not cool enough") 
     self.hair = hair 

例子:

In [15]: Human(123) 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-15-9998e6013647> in <module>() 
----> 1 Human(123) 

<ipython-input-13-65da6758e98d> in __init__(self, name, legs, hands, age, hair) 
     2  def __init__(self, name, legs=2, hands=2, age=0, hair='blonde'): 
     3   if not isinstance(name, str): 
----> 4    raise TypeError("Name must be a string") 
     5   self.name = name 
     6 

TypeError: Name must be a string 

另外一個..

In [16]: Human("John", age=1500) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-16-09f5670add7c> in <module>() 
----> 1 Human("John", age=1500) 

<ipython-input-13-65da6758e98d> in __init__(self, name, legs, hands, age, hair) 
    17 
    18   if age > 110: 
---> 19    raise ValueError("What, are you immortal?!") 
    20   self.age = age 
    21 

ValueError: What, are you immortal?!