0

I'm having trouble understanding nested classes and have a specific problem

I have a model "Pair" which has an attribute "name." I'd like to have a nested class called "History" that passes variables "start" and "end" as well as its parent (Pair) variable's "name". A @property decorated function would then return the standard deviation of that list.

To call the standard deviation I'd be looking for something like:

pair = Pair(base_currency='USD', quote_currency='GBP')
print(pair.History(granularity='1D', start=start_date, end=end_date).std_dev
>>> 634

I think it should look something like the below, but cant figure out how to inherit the outer class attribute "name"

class Pair:
    def __init__(self, base_currency, quote_currency):
        self.base_currency = base_currency
        self.quote_currency = quote_currency
        self.name = '{base}-{quote}'.format(base=base_currency, quote=quote_currency)
        self.history = self.History()

    class History:
        def __init__(self, granularity, start, end):
            self.name = HOW DO I GET THE PARENT NAME HERE
            self.granularity = granularity
            self.start = start
            self.end = end

        def data(self):
            return retrieve_history(product=self.name, granularity=self.granularity, start=self.start, end=self.end)

        @property
        def std_dev(self):
            return stdev(self.data)
slny06
  • 67
  • 11
  • Is your indentation correct? – Axe319 Jun 11 '21 at 17:25
  • As your question stands, here are some immediate problems I see. `pair = Pair(name)` will raise an error because your `Pair` class's `__init__` takes 2 arguments. `self.history = self.History()` won't work because your `class History:` isn't indented. It also wouldn't work because your `History` class's `__init__` takes 3 arguments. Your `stdev` method returns `return stdev(self.data)` but there is no outer `stdev` shown as defined. additionally You would only be handing the function the method object and not the return value. – Axe319 Jun 11 '21 at 17:34
  • Sorry it copy and pasted incorrectly (indents) and as for creating the Pair object, it was an error I didn't catch when I reposed the question. I've edited those out accordingly. Please ignor the stddev function details and just assume it is a function written elsewhere in the code (and imported before the models are defined. I understand the code won't work as is (re. self.History() and History.name, but I'm more so asking conceptually how one would arrange the models, attributes and methods to achieve the output for pair.History(granularity='1D', start=start_date, end=end_date).std_dev – slny06 Jun 11 '21 at 17:58
  • As it stands, your `History` class knows nothing about existing instances of the `Pair` class. The easiest option would be to hand the `History` class the `pair` instance on instantiation. So `self.history = self.History(some, args, pair_instance=self)` and `self.name = pair_instance.name` within your `History` `__init__`. – Axe319 Jun 11 '21 at 18:23
  • 1
    It seems like you might think that nesting classes means that they share instance state. That is not the case. See https://stackoverflow.com/a/2024583/12479639 – Axe319 Jun 11 '21 at 18:27
  • Yeh I think I got hung up on nesting classes sharing instance state. Ok backing up and symplfying. How could one achieve a structure in which this call would work: ClassInstance.SomeMethod(parameter=some_parameter).SomeAttribute – slny06 Jun 11 '21 at 19:21

0 Answers0