对齐Python类和超类

2024-04-25 14:23:37 发布

您现在位置:Python中文网/ 问答频道 /正文

考虑下面的Python代码片段,其中定义了PortfolioCompanyDeposit类。Portfolio对象只是充当公司和存款的联合体。我们可以在投资组合上运行类似Profit的度量。问题:

  1. 对于CompanyDeposit类中包含的每个新度量,我需要在Portfolio类中手动添加相应的函数;尽管它们的行为总是相同的:所有投资的总和。有没有办法改进类的逻辑/构造?如果我们需要添加100个其他指标。。。

  2. Deposit类只有一个Profit函数,但没有Loss(假设银行账户的利息是有保证的)。有没有一种方法可以将“未定义的”指标视为总是返回0?或者是否有更清晰/更正确的方法来定义这些指标?如果我们需要涵盖100种不同的投资类型,这些投资类型可能有或可能没有不同的衡量标准。。。


class Company():
    def __init__(self, ItemsSold, ItemPrice, Expenses, Fines):
        self.ItemsSold = ItemsSold
        self.ItemPrice = ItemPrice
        self.Expenses  = Expenses
        self.Fines     = Fines

    def Profit(self):
        return self.ItemsSold * self.ItemPrice

    def Loss(self):
        return self.Expenses + self.Fines

    def ProfitAndLoss(self):
        return self.Profit() - self.Loss()

class Portfolio():
    def __init__(self, Investments):
        self.Investments = Investments

    def Profit(self):
        return sum([inv.Profit() for inv in self.Investments])

    def Loss(self):
        return sum([inv.Loss() for inv in self.Investments])

    def ProfitAndLoss(self):
        return sum([inv.ProfitAndLoss() for inv in self.Investments])

class Deposit():
    def __init__(self, Notional, InterestRate, TimeHorizon):
        self.Notional     = Notional
        self.InterestRate = InterestRate
        self.TimeHorizon  = TimeHorizon

    def Profit(self):
        return self.Notional * self.InterestRate * self.TimeHorizon        

myComp1 = Company(100,2,50,20)
myComp2 = Company(200,2,100,80)
myDepos = Deposit(100,0.02,3)
myPortf = Portfolio([myComp1,myComp2,myDepos])

print(myPortf.Profit())          # Works fine
print(myPortf.ProfitAndLoss())   # Throws an error

Tags: selfreturndefcompanyportfolioprofitinvloss
1条回答
网友
1楼 · 发布于 2024-04-25 14:23:37

第二个问题很简单:您所要做的就是创建一个Base类,其中每个度量都定义为一个返回0的方法。然后从Base类派生所有Invest类(CompanyDeposit,等等),这样所有未定义的度量都将调用Base类中相应的方法。你知道吗

第一个问题有点难,因为它需要一些元编程。您的Portfolio类也可以从Base类派生,然后它在Base类(Base.__dict__)的方法字典中查找以检索所有度量名称。之后,对于所有这些度量,它将创建一个特定的lambda方法,该方法为Investments列表中的每个项目调用此度量,并对结果进行汇总。这是一个基本代码:

class Base(object):
    def f1(self):
        return 0
    def f2(self):
        return 0

class InvestA(Base):
    def f2(self):
        return 2

class InvestB(Base):
    def f1(self):
        return 1

class Portfolio(Base):
    def __init__(self, invest):
        self.invest = invest
        for name in [n for n in Base.__dict__ if n[:2] != '__']:
           self.__dict__[name] = lambda name=name: self.sum(name)
    def sum(self, name):
        return sum([i.__class__.__dict__[name](i) for i in self.invest
                   if name in i.__class__.__dict__])

A = InvestA()
print("A.f1 = %s, A.f2 = %s" % (A.f1(), A.f2()))
B = InvestB()
print("B.f1 = %s, B.f2 = %s" % (B.f1(), B.f2()))
P = Portfolio([A,A,B])
print('P.f1 = A.f1 + A.f1 + B.f1 =', P.f1())
print('P.f2 = A.f2 + A.f2 + B.f2 =', P.f2())

产生以下输出:

A.f1 = 0, A.f2 = 2
B.f1 = 1, B.f2 = 0
P.f1 = A.f1 + A.f1 + B.f1 = 1
P.f2 = A.f2 + A.f2 + B.f2 = 4

如您所见,A.f1、B.f2、p.f1和p.f2并没有明确定义为方法,但由于继承和元编程,它们可以被调用

相关问题 更多 >