【问题标题】:Calling a parent method from a child class with a variable of that child从具有该子变量的子类调用父方法
【发布时间】:2020-09-23 07:44:20
【问题描述】:

开始使用我的 Python Keitaro Admin API 库。我需要请求几个目标。像优惠、活动、流媒体或附属网络。他们有相似的请求 url,例如:

  1. https://example.com/v1/admin_api/offers 如果我需要与优惠互动
  2. https://example.com/v1/admin_api/campaigns 如果我需要与广告系列互动 等等。

我想在 python 代码中与 API 交互,如下所示: 使用类变量 url 和 api_key 创建类似对象 Keitaro。以及 get 和 post 等 keitaro 方法。然后将变量 'target' 添加到子类,这样我就可以使用报价或活动的 'target' 变量调用 Keitaro get/post 方法。

所需的代码模式:

from keitaropy import Keitaro

app = Keitaro('https://example.com/', 'api_key')
offer_of_app = app.offer.get(123) # get by id
offers_of_app = app.offer.get() # get all

app2 = Keitaro('https://otherurl.com/', 'other_api_key')
offer_of_app2 = app2.offer.get(11)
offers_of_app2 = app2.offer.get()

为什么我认为这段代码 sn-p 比下面的代码 sn-p 更好:我不需要导入像 Offer、Streams、Campaigns 这样的子类。我可以导入 Keitaro 类并通过调用这些类作为上述方法 offer/campaign/stream 来使用子对象的目标变量。

我取得了什么成就:

from keitaropy import Offer

offer_app = Offer('https://example.com/', 'api_key')
offer = offer.get(123)
offers = offer.get()

keitaropy 代码:

import requests
import json


def add_target_path(base_url, target, separator = '/'):
if base_url.endswith(separator):
    url = base_url + target
else:
    url = base_url + separator + target
return url

    
class Keitaro:
    def __init__(self, base_url, api_key, target):
        self.headers = { 'Api-Key': api_key }
        self.base_url = base_url
        self.target = target


    def get(self, target_id = None):
        url = add_target_path(self.base_url, self.target)
        if target_id:
            # get by id
            url = add_target_path(url, target_id)
        # if no id get all
        response = requests.get(url, headers=self.headers)
        return response.json()


    def post(self, data):
        pass


class Offer(Keitaro):
    def __init__(self, base_url, api_key):
        self.target = 'offers'
        super().__init__(base_url, api_key, self.target)


class Campaign(Keitaro):
    def __init__(self, base_url, api_key):
        self.target = 'campaigns'
        super().__init__(base_url, api_key, self.target)


class Stream(Keitaro):
    def __init__(self, base_url, api_key):
        self.target = 'streams'
        super().__init__(base_url, api_key, self.target)


class AffNetwork(Keitaro):
    def __init__(self, base_url, api_key):
        self.target = 'affiliate_networks'
        super().__init__(base_url, api_key, self.target)

我不喜欢将子变量“target”存储在父类中只是为了调用父方法 get 的想法,但没有任何想法可以更好地做到这一点。如果你有什么想法请和我分享

此外,子类 Campaign、Offer 等也可以有自己的方法,这些方法不是父类中固有的。

【问题讨论】:

  • 如果有任何示例如何实现第一个代码 sn-p 仍然会很好!所以我可以将父属性用于多个优惠,例如
  • 在这个问题中添加了更多细节stackoverflow.com/questions/64026236/…

标签: python python-3.x oop python-requests


【解决方案1】:

父类具有像target 这样的属性,它直接使用它并没有错。子类设置值也没有错:

class Offer(Keitaro):
    def __init__(self, base_url, api_key):
        super().__init__(base_url, api_key, 'offers')

您刚刚获得了一个好处,像 OfferCampaign 这样的类减少了实例化类所需的参数数量。

【讨论】:

  • 我认为是这样,但是我如何更改代码以从具有子属性(例如“优惠”)的父类调用 get 方法,就像我在上面的“所需代码模式”中提到的那样。这是主要问题
  • 你指的是哪个child attribute
  • target = 'offers' 例如,我想将它传递给父类以调用使用父属性的 get 方法,并希望像上面有问题的“所需代码模式”中那样调用此方法跨度>
  • 如果你的第一个代码 sn-p 是你的Desired code pattern 而你的第二个是你已经取得的成就,我更喜欢你的第二个。干净多了。
  • 我希望用户能够使用不同的 api_keys 和 url 创建多个应用程序 Keitaro。并使用 Offer/Campaign/AffNetwork/Streams 属性和方法
【解决方案2】:

您可以避免通过构造函数传递“目标”变量,而是直接从子中的首选方法调用父 get 方法,同时将目标作为参数传递。

【讨论】:

    【解决方案3】:

    这个问题的答案比我预期的要复杂。例子你可以查看我的GitHub repo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-11
      • 1970-01-01
      • 2012-02-22
      • 2017-11-09
      • 2012-10-28
      • 1970-01-01
      • 1970-01-01
      • 2023-03-21
      相关资源
      最近更新 更多