1

我正在使用Markana 教程学习 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

4 回答 4

2

要为 BrenBarn 的答案添加更多细节——是的,你想覆盖__contains__. x in object成员资格测试仅使用if__iter__未定义__contains__

似乎您希望__contains__同时为 Investment 实例和 Investment 名称字符串工作,因为我假设您既想要'GOOG' in pinvestment_object_with_GOOG_name in p想要 return True。如果是这种情况,代码应该如下所示:

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

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

    # checks investment objects by comparing to dictionary keys
    if isinstance(item, Investment) and item.name in self.d_investments:
        return True

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

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

于 2012-06-10T02:45:43.527 回答
1

很难看出您要做什么,但我认为一种可能性是覆盖__contains__您的类以返回 True 如果它传递了与股票名称相对应的字符串。请参阅文档

于 2012-06-10T01:55:37.943 回答
0

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

于 2012-06-10T05:20:12.513 回答
0

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

于 2012-06-10T01:56:55.647 回答