Gerard
Gerard

Reputation: 117

How can I use attributes from the class above?

I made an outer class with a function to create a path of folders, user decides the path and inner class to save the plot image to that folder, user decides on file name and format. My problem is that I can't use the outer class attributes. How can I use attributes from the class above? Is there another clean way of such a dependency?

import os
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
import pandas as pd

# Outter class
class Folders():
    def __init__(self,
        base_path="folder_name1/folder_name2"):
        self.base_path = base_path
        pass
# Function to create path of folders
    def create(self):
        try:
            os.makedirs(self.base_path)
        except FileExistsError:
            # directory already exists
            pass
# Inner class
    class Save:
        def __init__(self,current_date = datetime.today().strftime('%Y_%m_%d@%H_%M_%S'),
                     image_format = '.png',
                     image_name = '/name_of_image'):
            self.current_date = current_date
            self.image_name = image_name
# Function to save the images in the created path
        def image1(self):
            f.savefig(self.base_path+self.image_name+self.image_format, bbox_inches='tight')

# Plotting the figure
x = np.linspace(0, 6*np.pi, 100)
y = np.sin(x)
f = plt.figure()
ax = f.add_subplot(111)
ax.plot(x, y, 'r-')

# Creates path of folders
folder = Folders()
folder.create()

# Save images with default arguments
save = folder.Save()
save.image1()

# Save images with chosen arguments
savea = folder.Save(image_format='.jpg', image_name='image_name')
savea.image1()

Upvotes: 1

Views: 57

Answers (1)

Karl Knechtel
Karl Knechtel

Reputation: 61526

Looking at the code more closely and making the guess that by "self.arguments" you mean "attributes of self": you seem to be under the impression that the inner class is somehow associated with the outer class, such that instances of the inner class implicitly have some instance of the outer class created along with them. In Python, this is not the case. self.base_path cannot resolve to the base_path attribute of some Folders instance because self is not a Folders instance; it is a Save instance, and Save is not a subclass of Folders. It is merely defined within Folders, which is merely namespacing (i.e., outside code needs to refer to the class as Folders.Save rather than just Save).

You should redesign this completely. None of this makes sense design-wise in the first place: what does it mean to say that you have "a Folders", or "a Save"? What are those things? Remember, "object" is a fancy word for thing, and "class" is a fancy word for "kind of thing".

Anyway, the natural way to provide information to an instance of a class is to pass it to the constructor, and then have __init__ store that information somewhere. You know, like you are already doing when you create the Folders instance in the first place.

Upvotes: 2

Related Questions