【问题标题】:How to set parameter for all of the methods in Inherited class如何为继承类中的所有方法设置参数
【发布时间】:2020-08-20 18:06:55
【问题描述】:

我目前正在学习 Python 中的面向对象编程。我在理解如何传递给我从 Parten 类继承的所有方法方面遇到了一些问题。我将向您展示代码示例。

您可以在下面看到我的 Parent 类(它是简单的 api 包装器)。

class AlphaVantageClient:

    _URL = "https://www.alphavantage.co/query?"

    def __init__(self, api_key=None):
        self.__api_key = api_key

    def show_base_url(self):
        print(self._URL)

    def set_api_key(self, api_key: str):
        self.__api_key = api_key

    def __call_api(self, query_parameters: dict,**kwargs):
        """
        The structure looks like:
            co./query?function{}&symbol{}
        :param query_parameters:
        :return: response
        """
        query_parameters["apikey"] = self.__api_key

        response = requests.get(
            AlphaVantageClient._URL,
            params=query_parameters,
            proxies=self.__proxy
        )

        validate_http_status(response)
        return response.json()

    def company_overview(self, ticker: str, **kwargs):
        query_parameters = {
            "function": "OVERVIEW",
            "symbol": ticker
        }
        return self.__call_api(query_parameters, **kwargs)

    def balance_sheet(self, ticker: str, **kwargs):
        query_parameters = {
            "function": "BALANCE_SHEET",
            "symbol": ticker
        }
        return self.__call_api(query_parameters, **kwargs)

    def income_statement(self, ticker: str, **kwargs):
        query_parameters = {
            "function": "INCOME_STATEMENT",
            "symbol": ticker
        }
        return self.__call_api(query_parameters, **kwargs)

    def cash_flow(self, ticker: str, **kwargs):
        query_parameters = {
            "function": "CASH_FLOW",
            "symbol": ticker
        }
        return self.__call_api(query_parameters, **kwargs)

下面是我的子类,我想从AlphaVantageClient类继承所有方法。

class Stock(AlphaVantageClient):
    def __init__(self, ticker: str):
        super().__init__()
        self.ticker = ticker
        self.client = AlphaVantageClient()

    def set_api_key(self, api_key):
        self.client.set_api_key(api_key)

但我的问题是,正如您在AlphaVantegeClient 中看到的那样,我的所有方法都有参数symbol,我想在一行或类似的内容中设置所有方法都有我的symbol 参数集从Stock 类到self.ticker。有可能这样做吗?或者我需要以某种方式重构父类代码?

【问题讨论】:

  • 因此在AlphaVantageClient.__init__ 中接受ticker 并将其存储为self.ticker,就像您对self.__api_key 所做的那样
  • 并且可以根据self.ticker给符号参数赋予默认值
  • 伙计们,你能看看我下面的答案。我认为我们彼此不了解,或者我只是不知道如何实施您的解决方案。

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


【解决方案1】:

您误解了继承的工作原理。当您创建一个子类(继承自)AlphaVantageClient 的类 Stock 时,它会自动获取该父类的所有属性和方法,就像您将它们定义为新子类的一部分一样。

您绝对不应该在 init 中包含这一行:self.client = AlphaVantageClient()。通过从AlphaVantageClient 子类化(继承)它已经是AlphaVantageClient 的一个实例,并创建了一个单独的附加实例和AlphaVantageClient 与它所在的实例分开。

在您的Stock 类中,您不必重新定义set_api_key(),除非您出于某种原因尝试更改它而您没有。此方法只是尝试将api_key 保存到内部类属性中,并且它已经这样做了,所以只需将其保留/取消在Stock 中重新定义。

您不需要重做AlphaVantageClient,但您确实需要在Stock 中有存根,因为它们需要将保存的ticker 参数替换为对父级的调用。像这样:

class Stock(AlphaVantageClient):
    def __init__(self, ticker: str, api_key=None):
        super().__init__(api_key)
        self.ticker = ticker
        
    def company_overview(self, **kwargs):
        return super().company_overview(self.ticker, **kwargs)

    def balance_sheet(self, **kwargs):
        return super().balance_sheet(self.ticker, **kwargs)

    def income_statement(self, **kwargs):
        return super().income_statement(self.ticker, **kwargs)

    def cash_flow(self, **kwargs):
        return super().cash_flow(self.ticker, **kwargs)

【讨论】:

  • 非常感谢。你刚刚澄清了很多我不明白的未知数。
【解决方案2】:

谢谢你的回答。我不知道我是否理解正确。

class AlphaVantageClient:

    _URL = "https://www.alphavantage.co/query?"

    def __init__(self, api_key=None, symbol=None):
        self.__api_key = api_key
        self.__proxy = {}
        self.__validate_api_key()
        self.__data_type = 'json'
        self.__symbol = symbol

    def set_api_key(self, api_key: str):
        self.__api_key = api_key

    def __call_api(self, query_parameters: dict,**kwargs):
        """
        The structure looks like:
            co./query?function{}&symbol{}
        :param query_parameters:
        :return: response
        """
        query_parameters["apikey"] = self.__api_key

        response = requests.get(
            AlphaVantageClient._URL,
            params=query_parameters,
            proxies=self.__proxy
        )

        validate_http_status(response)
        return response.json()

    def company_overview(self, symbol: str, **kwargs):
        query_parameters = {
            "function": "OVERVIEW",
            "symbol": symbol
        }
        return self.__call_api(query_parameters, **kwargs)

    def balance_sheet(self, symbol: str, **kwargs):
        query_parameters = {
            "function": "BALANCE_SHEET",
            "symbol": symbol
        }
        return self.__call_api(query_parameters, **kwargs)

    def income_statement(self, symbol: str, **kwargs):
        query_parameters = {
            "function": "INCOME_STATEMENT",
            "symbol": symbol
        }
        return self.__call_api(query_parameters, **kwargs)

    def cash_flow(self, symbol: str, **kwargs):
        query_parameters = {
            "function": "CASH_FLOW",
            "symbol": symbol
        }
        return self.__call_api(query_parameters, **kwargs)

class Stock(AlphaVantageClient):
    def __init__(self, symbol: str):
        super().__init__(symbol)
        self.symbol = symbol
        self.client = AlphaVantageClient(symbol)

    def set_api_key(self, api_key):
        self.client.set_api_key(api_key)

现在我的课程看起来像这样。我尝试创建我的类的实例并调用如下方法之一:

from client import AlphaVantageClient, Stock

stock = Stock(symbol="FB")
stock.income_statement()

我得到一个错误:

tests\test_client.py:5: in <module>
    stock.income_statement()
E   TypeError: income_statement() missing 1 required positional argument: 'symbol'

所以我不知道是我没有正确理解您,还是我只是以错误的方式解释了我的问题。所以我会再试一次:

如果我调用我的AlphaVantageClient,我想以创建该类实例的方式使用它,并调用作为股票参数符号提供的方法,例如

client = AlphaVantageClient()
income_statement = client.income_statement(symbol="FB")

但是,如果我创建一个 Stock 类,我希望将符号存储在类中,并且不需要在我的方法中将其作为参数提供:所有方法都应该使用我在创建 @ 时提供的符号默认为 987654327@ 类。所以用法应该如下所示:

stock = Stock(symbol="FB")
income_statement = stock.income_statement()

这样我将在我的所有方法中获取“FB”的数据。

有可能吗?如果是的话,你能解释一下如何实现它吗?

【讨论】:

    猜你喜欢
    • 2011-08-16
    • 2019-07-27
    • 2014-11-24
    • 2013-04-17
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多