元组问题

时间:2015-05-03 20:29:54

标签: python oop tuples

我在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时,我的代码按预期工作,但是,当输入元组时,我似乎无法弄明白。有什么想法吗?

3 个答案:

答案 0 :(得分: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))

或在构造函数声明中使用'*'运算符。

答案 1 :(得分: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'

答案 2 :(得分:1)

您的代码中存在许多问题,从格式化到功能。最重要的是:

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

因此,如果用户传递数字英尺,则假设它实际上是英寸?为什么呢?!

我认为你从根本上误认为你打电话时会发生什么。

Height(5, 10)

__init__内,这有效地设置了ft = 5inch = 10 ft = (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"

还请注意使用str.format并遵守the style guide。另一种选择是在inches > 11 and feet > 0时引发错误,因为这可能是错误的输入。您可能还想查看emulating numeric types