Python - __iter__方法返回实例.__ str__和instance.name?

时间:2012-06-10 01:46:16

标签: python oop class iterator

我正在使用Markana tutorial学习OOP python,而我在使用Lab 16.8时遇到了一些麻烦。 (在其他一些麻烦中)我无法使__iter__方法正确。我的方法如下:

def __iter__(self):
        for e in self.l_investments:
            yield e

这是我的代码(以及运行它的结果):http://hastebin.com/wayuwakode.py

以下是应该出现的结果:

>>> 'GOOG' in p
True

我明白了:

>>> 'GOOG' in p
False

p是类Portfolio()的一个实例。 'GOOG'是Investment()对象实例的.name属性。 p包含一个列表和一个Investment()实例的字典。

我可以更改__iter__方法以生成名称:

def __iter__(self):
    for e in self.l_investments:
        yield e.name

这会修复它'GOOG' in p == True,但它打破了另一个要求:

Failed example:
    for stock in p:
        print stock
Expected:
    1000 shares of APPL worth 252730.00
    5000 shares of CSCO worth 118700.00
    500 shares of GOOG worth 245670.00
    2000 shares of MSFT worth 50880.00
Got:
    APPL
    CSCO
    GOOG
    MSFT

如何更改__iter__方法(或代码的任何其他部分)以满足这两个要求?

我对学习OOP如何工作比解决这个特定问题更感兴趣。任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:2)

要向BrenBarn的答案添加更多细节 - 是的,您要覆盖__contains__。如果未定义x in object,则__iter__成员资格测试仅使用__contains__

您似乎希望__contains__适用于投资实例和投资名称字符串,因为我假设您希望'GOOG' in pinvestment_object_with_GOOG_name in p都返回{{ 1}}。如果是这种情况,代码看起来应该是这样的:

True

请注意,投资对象需要实现合理的比较才能实现。如果它们没有(看起来它们没有 - 对象比较使用ID而不是属性内容),要么给它们一个比较运算符,要么用这个版本替换上面的后半部分来进行比较名:

def ___contains___(self, item):
    # checks investment name strings by comparing to dictionary keys
    if item in self.d_investments:
        return True
    # checks investment objects by comparing to dictionary values
    if item in self.d_investments.values():
        return True

当然,如果您希望成员资格测试仅适用于名称字符串,则只需删除后半部分。

此外,在查看您的代码之后 - 您是否有任何理由保留投资组合中的列表和投资字典?两者都应该足以作为内部表示。我在上面的代码中使用了字典,但是用列表重新实现很容易 - 我认为你应该选择一个,除非你真的需要性能或其他原因,我还没有从代码中找到

答案 1 :(得分:1)

有点难以看到你正在尝试做什么,但我认为有一种可能性是覆盖你的类上的__contains__,如果传递了与股票名称相对应的字符串,则返回True。请参阅the documentation

答案 2 :(得分:0)

我认为Lattyware有正确的答案,定义__eq__以便投资可以等于一个字符串。

答案 3 :(得分:0)

您可能应该在__eq__课程中添加Investment函数(因为这是您实际返回的内容。在这种情况下,您需要检查是否self.name == other.name。您可以这样做,或者您可以像其他人建议的那样添加__contains__功能。