5

时隔 20 年,我才刚刚回到编程领域。我认为 Python 看起来相当简单和强大,所以我做了一个在线课程和一些阅读。

我现在正在研究一些简单的项目来熟悉该语言。挑战之一是让我了解面向对象编程,这在我上次编写程序时还没有。

我的第一个项目是读入一个包含股票投资组合信息的数据文件,对每个文件进行一些计算并打印一份报告。我有这个工作。

所以现在我正在研究更高级的东西,读取数据并存储它,然后使用数据为交互式问题提供答案。我的问题是如何存储数据以便可以轻松访问。

我的第一个想法是列出一个列表,例如,

companies = [ ['AMP', 1000, 2.50], ['ANZ', 2000, 17.00], ['BHP', 500, 54.30] ]

这可以很容易地在循环中访问,但访问方法并不完全友好 - 数字作为索引而不是名称:

companyqty = companies[1][1]

或 for 循环:

for company in companies:
    if company[0] == 'BHP':
        companyqty = company[1]

然后我想到了一个字典,它的值是一个列表:

companies = {'AMP':[1000, 2.50], 'ANZ':[2000, 17.00], 'BHP':[500, 54.30] }
companyqty = companies['BHP'][0]

这提供了对任何给定公司的即时访问,但仍然停留在数字索引上。

所以我想知道如何以面向对象的方式构造它,以便能够保存公司列表和所有相关数据,并能够方便地访问这些值。到目前为止,我所有的想法看起来都像上面的列表或字典。

或者这类问题是否真的不适合面向对象的方法?

谢谢

4

4 回答 4

4

对于 OOP 方法来说,这是一个很好的问题。例如,您可以为特定的投资组合股票创建一个类,该类具有公司名称、股份数量和股价的属性。你可以给它一些有用的功能,比如getValue. 这是一个示例实现:

class Holding:
    def __init__(self, companyName, numShares, sharePrice):
        self.companyName = companyName
        self.numShares = numShares
        self.sharePrice = sharePrice
    def getValue(self):
        return self.numShares * self.sharePrice

portfolio = {'AMP':Holding('AMP', 1000, 2.5), 'ANZ':Holding('ANZ', 2000, 17.0), 'BHP':Holding('BHP', 500, 54.30)}

print portfolio['BHP'].sharePrice
# 54.3
print portfolio['AMP'].getValue()
# 2500.0

您可以通过属性名称访问您的馆藏属性。你可以把它提升到一个新的水平,也可以为投资组合编写一个类,它可以具有“holdingList”和“broker name”等属性,以及“getTotalValue”等函数。

于 2013-08-17T15:25:58.013 回答
3

您的下一步可能是使用collections.namedtuple()工厂生成的类:

from collections import namedtuple

Company = namedtuple('Company', 'quantity price')

companies = {'AMP': Company(1000, 2.50), 'ANZ': Company(2000, 17.00), 'BHP': Company(500, 54.30)}

companies['AMP'].quantity

请注意,与tuple对象一样,-namedtuple派生对象是不可变的。您不能分配给属性,而是创建一个新对象。

如果您需要向对象添加功能,则只需要切换到自定义类;添加作用于与对象关联的数据的方法:

class Company(object):
    def __init__(self, quantity, price):
        self.quantity = quantity
        self.price = price

    def profit(self, newprice):
        return self.quantity * (newprice - self.price)
于 2013-08-17T15:24:25.987 回答
1

您还可以使用嵌套字典:

companies =
   {
      'AMP': {'quantity':1000, 'price': 2.50},
      'ANZ': {'quantity':2000, 'price': 17.00},
      'BHP': {'quantity':500, 'price': 54.30}
   }

并像这样访问它:

companyqty = companies['BHP']['quantity']

您甚至可以为公司定义额外的“属性”:

companies =
   {
      'AMP': {'quantity':1000, 'price': 2.50, 'foundation_date': '2013-01-01'},
      'ANZ': {'quantity':2000, 'price': 17.00},
      'BHP': {'quantity':500, 'price': 54.30, 'head': 'Jeffrey'}
   }
于 2013-08-17T15:28:02.763 回答
0

即便如此,在 Python 中也只有一种方法可以做事,这个问题的答案实际上取决于什么是“可以轻松访问”。

这是否意味着程序员很容易访问对象及其属性?那么最好的方法是让 Company 成为该类的一个实例,并提供价格、数量等属性。可能将类称为 Portfolio 是矫枉过正的,除非除了列表或字典之外,您还有非平凡的逻辑。也可以基于字典创建类,因此可以通过键和属性访问。这就是我所说的容易访问。看一下webpy框架的Storage类:以https://github.com/webpy/webpy/blob/master/web/utils.py#L52为例。

如果“轻松访问”意味着第三方库将对数据进行一些序列化或其他处理,那么最简单的方法是使用库所期望的数据结构。例如,JSON 格式与 Python 的列表和字典非常匹配(请参阅 Roman Pekar 的答案)。

于 2013-08-17T16:46:51.857 回答