1

Markanaチュートリアルを使用してOOPpythonを学習していますが、 Lab16.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メンバーシップテストは、が定義されていない場合にのみ使用します__iter____contains__

__contains__InvestmentインスタンスとInvestment名の文字列の両方で機能するように思われます。これは、両方が必要で'GOOG' in pあり、investment_object_with_GOOG_name in pが返されると想定しているためです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

これを機能させるには、Investmentオブジェクトが適切な比較を実装する必要があることに注意してください。そうでない場合(そうではないように見えます—オブジェクトの比較では属性の内容ではなくIDが使用されます)、比較演算子を指定するか、上記の後半をこのバージョンに置き換えて、名前:

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

もちろん、メンバーシップテストを名前文字列に対してのみ機能させたい場合は、後半を完全に削除してください。

また、コードを見た後、ポートフォリオへの投資のリストと辞書を保持する理由はありますか?内部表現としてはどちらでも十分なはずです。上記のコードには辞書を使用しましたが、リストを使用して再実装するのは簡単です。パフォーマンスやコードから理解できないその他の理由で両方が本当に必要な場合を除いて、1つだけ選択する必要があると思います。 。

于 2012-06-10T02:45:43.527 に答える
1

何をしようとしているのかを理解するのは少し難しいですが、1つの可能性は__contains__、株の名前に対応する文字列が渡された場合にTrueを返すようにクラスをオーバーライドすることだと思います。ドキュメントを参照してください。

于 2012-06-10T01:55:37.943 に答える
0

Lattywareには正しい答えがあると思います__eq__。投資が文字列に等しくなるように定義してください。

于 2012-06-10T01:56:55.647 に答える
0

おそらく、クラスに__eq__関数を追加する必要がありますInvestment(これは、実際に返されるものだからです。この場合、確認する必要があります。それを実行するか、他の人が提案したようself.name == other.nameに関数を追加できます。__contains__

于 2012-06-10T05:20:12.513 に答える