2015-05-03 92 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