2015-05-03 94 views
3

我在Python中做了一些OOP,當用戶輸入一個元組作爲參數之一時遇到了麻煩。下面的代碼:元組麻煩

class Height: 
    def __init__(self,ft,inch=0): 
     if isinstance(ft,tuple): 
      self.feet = ft 
      self.inches = inch 
     elif isinstance(ft,int): 
      self.feet = ft // 12 
      self.inches = ft % 12 
    def __str__(self): 
     return str(self.feet) + " Feet " + str(self.inches) + " Inches" 
    def __repr__(self): 
     return "Height (" + str(self.feet * 12 + self.inches) + ")" 

我試圖想初始化英寸爲0,將有助於東西出來,但沒有奏效。元組也不支持索引,因此該選項也不存在。我覺得答案很簡單,我只是在推翻它。我使用的測試代碼:

from height import * 
def test(ht): 
    """tests the __str__, __repr__, and to_feet methods for the height 
    Height->None""" 
    #print("In inches: " + str(ht.to_inches())) 
    #print("In feet and inches: " + str(ht.to_feet_and_inches())) 
    print("Convert to string: " + str(ht)) 
    print("Internal representation: " + repr(ht)) 
    print() 
print("Creating ht1: Height(5,6)...") 
ht1 = Height(5,6) 
test(ht1) 
print("Creating ht2: Height(4,13)...") 
ht2 = Height(4,13) 
test(ht2) 
print("Creating ht3: Height(50)...") 
ht3 = Height(50) 
test(ht3) 

我的代碼工作時int輸入,但同樣,我似乎無法弄清楚當一個元組輸入如預期。有任何想法嗎?

+4

元組支持索引。 –

+0

問題標題中有一個星際迷航引用可以從我這裏得到upvote :) – krock

+1

@PadraicCunningham(從什麼時候開始'a =(2,0); print(a [0])'拋出IndexError?元組支持索引.. )對不起,忘了我說過的話,我誤解了你的評論......我的道歉! – Spirine

回答

4

你真的被傳遞一個元組嗎?在我看來,你的構造函數應該簡單地:

def __init__(self, ft, inch=0): 
    self.ft = int(ft) 
    self.inch = int(inch) 

,如果您使用任何這些創建對象(因爲你的inch參數的默認值)工作原理:

foo = Height(6) 
bar = Height(6, 3) 
baz = Height("5", 3) 

等請注意,在第二個和第三個實例中,您仍然沒有傳遞一個元組。爲了真正得到一個元組,你需要這樣稱呼它:

foo2 = Height((6, 3)) 

或在構造函數聲明中使用「*」運算符。

+0

儘管這是更好的方法,但我應該指出,如果只有一個參數,Trevor的Height對象將「ft」解釋爲以英寸爲單位。 – cge

+0

好點。實際上,在任何一個單位(英尺或英寸[或毫米或其他])內部保持內部價值更有意義,然後根據需要將其轉換爲人熟悉的英尺/英寸輸出。 –

1

元組支持索引。它們不支持索引分配,因爲它們是不可變的,但支持索引訪問。

您的代碼不工作,因爲您的代碼旨在接受ft中的元組。它沒有對int做任何事情,這是一個完全不同的論點。所有你需要做的就是使用索引來代替:

class Height: 
    def __init__(self,ft,inch=0): 
     if isinstance(ft,tuple): 
      self.feet = ft[0] 
      self.inches = ft[1] 
     elif isinstance(ft,int): 
      self.feet = ft // 12 
      self.inches = ft % 12 
    def __str__(self): 
     return str(self.feet) + " Feet " + str(self.inches) + " Inches" 
    def __repr__(self): 
     return "Height (" + str(self.feet * 12 + self.inches) + ")" 

但是,這隻能如果你真的在傳遞一個元組,你的測試代碼永遠不會! Height(5,6)只是傳入兩個參數。對於元組輸入,你需要Height((5,6))

正如其他人已經指出,你調用它的方式實際上比使用元組更有意義。要獲得工作,你只需要看看是否正在使用您的第二個參數(讓我們更改爲v1和v2,原因我會得到更高版本):

def __init__(self, v1, v2=None): # set v2 to None, and then check to see if it isn't None 
    if v2 is not None: 
     self.feet = v1 
     self.inches = v2 
    else: 
     self.feet = v1 // 12 
     self.inches = v1 % 12 

但是,這有一個可用性問題:第一個參數的含義取決於在那裏是否有第二個參數!這就是爲什麼命名它ft特別糟糕:如果沒有提供第二個參數,它實際上是以英寸爲單位!

一種解決方法是讓參數有名字,讓用戶選擇他們想要使用的:

def __init__(self, feet=0, inches=0): 
    self.feet = feet + inches // 12 
    self.inches = inches % 12 

那麼你有很多選擇,和更少的機會困惑:

In [4]: str(Height(5,0)) 
Out[4]: '5 Feet 0 Inches' 

In [5]: str(Height(0,5)) 
Out[5]: '0 Feet 5 Inches' 

In [6]: str(Height(5)) 
Out[6]: '5 Feet 0 Inches' 

In [7]: str(Height(inches=25)) 
Out[7]: '2 Feet 1 Inches' 

In [8]: str(Height(feet=3,inches=25)) 
Out[8]: '5 Feet 1 Inches' 
+0

現在應該更清楚了。 – cge

1

從代碼格式到功能,您的代碼都有很多問題。最重要的是這樣的:

elif isinstance(ft,int): 
    self.feet = ft // 12 
    self.inches = ft % 12 

因此,如果用戶通過在腳一些,它的假設實際上是英寸?爲什麼?!


我認爲你根本錯誤地發生了什麼,當你打電話時,

Height(5, 10) 

裏面__init__,這有效地設置ft = 5inch = 10ft = (5, 10)


以下是我我也會那樣做:

class Height: 

    def __init__(self, feet=0, inches=0): 
     self.feet, self.inches = feet, inches % 12 
     self.feet += inches // 12 

    def __str__(self): 
     return '{0.feet}\' {0.inches}"'.format(self) 

    def __repr__(self): 
     return 'Height({0.feet}, {0.inches})'.format(self) 

這允許任何以下才能正常工作:

>>> Height() 
Height(0, 0) 
>>> Height(5, 0) 
Height(5, 0) 
>>> Height(5) 
Height(5, 0) 
>>> Height(inches=60) 
Height(5, 0) 
>>> print(str(Height(inches=123))) 
10' 3" 

還要注意與the style guide使用str.format和合規性。另一種選擇是如果inches > 11 and feet > 0發生錯誤,則可能是錯誤的輸入。你可能也想看看emulating numeric types