我在下面有一个名为Row的模型。我必须基于一个基本模型创建多个模型。

class Row:
    def __init__(self, 
             date=None, 
             cost=None, 
             currency=None):
        self.date = date
        self.cost = cost
        self.currency = currency

    def to_dict(self):
        return {
            "date": self.date,
            "cost": self.cost,
            "currency": self.currency
    }

    def __repr__(self):
        return "%s(Date: %s, Cost: %s, Currency: %s, ConversionRt: %s, CampaignId: %s)" % (self.__class__.__name__, 
                  self.date, self.cost, \
                  self.currency)

子类示例如下:

class ChildRow(Row):
    def __init__(self, row, metrics):
        super().__init__(
            self.assign_rows(row, metrics)
        )

    def assign_rows(self,
                    row,
                    metrics):
        self.date = metrics['date']
        self.cost = metrics['cost']['amount']
        self.currency = row['localSpend']['currency']

子类将需要接受多个json响应字典,并提取某些参数并将其分配给每个属性。由于某些原因,我无法使它与以下有效负载一起使用。出于某种原因,这些属性将不会设置。

row = {'localSpend': {'currency': 'USD'}}
metrics = {'date': '20190401', 'cost': {'amount': 290.5999}}

如果我创建ChildRow实例,我期望它会自动启动assign_rows并将数据设置为属性。有什么想法我在这里做错了吗?子类为所有属性返回None。我也愿意接受不同或更好的建模想法。谢谢

分析解答

您对这里的工作方式有一个奇怪的了解。您的代码将执行以下操作:

  • 调用assign_rows,它分配实例属性的值
  • (implicitly)从该方法返回None
  • 将返回值(即None)传递给父类__init__方法。
  • 该方法将None值作为date参数的值。其他两个参数使用其默认值,也均为“无”。
  • 所有这三个None值都分配给了实例属性,从而覆盖了您先前在assign_rows中设置的值。

因此,总而言之,将设置值,但随后将其覆盖为None。

我不知道您为什么认为需要将函数的结果传递给超级调用。设置值;您可以完全跳过超级。只是这样做:

class ChildRow(Row):
    def __init__(self, row, metrics):
        self.assign_rows(row, metrics)

或者,也可以将逻辑从assign_rows直接移到__init__,然后再次跳过调用super:

class ChildRow(Row):
    def __init__(self, row, metrics):
        self.date = metrics['date']
        self.cost = metrics['cost']['amount']
        self.currency = row['localSpend']['currency']