我正在使用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如何工作比解决这个特定问题更感兴趣。任何帮助将不胜感激!
答案 0 :(得分:2)
要向BrenBarn的答案添加更多细节 - 是的,您要覆盖__contains__
。如果未定义x in object
,则__iter__
成员资格测试仅使用__contains__
。
您似乎希望__contains__
适用于投资实例和投资名称字符串,因为我假设您希望'GOOG' in p
和investment_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__
功能。