0

I've got couple of huge tables with data called bnds.data and densities.data. I've also got a class processing those data tables. That class is called in a loop and in order to avoid repetitive and time demanding loading those data tables into memory, I want to creat another class and initialise some variables in there. Here's a piece of code giving the idea of what I want to do:

import numpy as np

class Pixel:
    def  __init__(self):
        self.bounds = np.loadtxt('bnds.data')
        self.rho = np.loadtxt('densities.data')

class Density(Pixel):

    def __init__(self, pixel, phi, theta):
        self.phi = phi
        self.theta = theta
        latitude =  int(90 - self.phi +1)
        longitude = int(180 + self.theta + 1)
        n = (latitude -1)*360 + longitude -1
        self.rho = pixel.bounds[n]

    def print_rho(self):
        print (self.rho)

pixel = Pixel()
rho = Density(pixel, 10, 20) # phi = 10, theta = 20
rho.print_rho()

Here , the instance of Pixel is sent to class Density. The data loading is done in the Pixel class. The density class will be called in a loop. What I don't quite understand is whether the Pixel class will be initialized every time the Density class is called? If yes then how to avoid it? My guess is that the Pixel class is initialized once and for all regardless of how many time the Density class is called. Is it correct? phi and theta are variables and they take different values in a loop. What I need is the bnds.data & densities.data tables to be loaded once and for all.

3
  • Yes, it is correct. As long as you only instantiate one Pixel object as you have done above, you can make multiple Density objects that reference the pixel data. Commented Feb 27, 2016 at 23:03
  • @Alexander just to clarify, you mean if I write something like this: for i in range(90): rho = Density(pixel,i,i) the Pixel class will be referenced only once? Commented Feb 27, 2016 at 23:31
  • 1
    It will be referenced many times, but created only once. And don't inherit Pixel from Density. Just class Density(object): Commented Feb 27, 2016 at 23:32

2 Answers 2

1

In general - yes, with current code, Pixel's __init__ is only executed once. However, there is no need for Density to be a subclass of Pixel, it shares no resemblance or functionality.

A more sensible solution would be to have a method on Pixel, which returns a Density, which is required for initialization of Density, eg:

class Pixel:
    def  __init__(self):
        self.bounds = np.loadtxt('bnds.data')
        self.rho = np.loadtxt('densities.data')

    def get_density(self, phi, theta):
        return Density(self, phi, theta)

pixel = Pixel()
rho = pixel.get_density(10,20) # phi = 10, theta = 20
rho.print_rho()

That way you make your code more readable.

Note that classes can be quite expensive if performance is critical. If you're only calculating rho, you could also turn the whole Density class to a get_rho(phi, theta) method avoiding instantiating a new class at all.

Sign up to request clarification or add additional context in comments.

2 Comments

Keep on doing the good work, one day at a time makes a huge effort in a year!
yeah I will try! By the way, do you know if it's usually considered a good practice to make some simple calculations in __init__? For example, is it okay if I write anything like that: self.v_x = dx/dt, where "dx" and "dt" are the input variables?
0

First off, when you are using inheritance you don't need to pass an instance of parent class to child class. That's what you are using inheritance.

You can simply access to your parent class attributes within your child class after calling the parent constructor using super() in pyhton 3 and new_style classes in python 2 or directly call it in old_style classes. And then you'll be sure that after each instantiate bnds.data and densities.data tables will be loaded once.

class Pixel:
    def  __init__(self):
        self.bounds = np.loadtxt('bnds.data')
        self.rho = np.loadtxt('densities.data')

class Density(Pixel):
    def __init__(self,phi,theta):
        super(Density, self).__init__()
        self.phi = phi
        self.theta = theta
        latitude =  int(90 - self.phi +1)
        longitude = int(180 + self.theta + 1)
        n = (latitude -1)*360 + longitude -1
        self.new_rho = self.bounds[n]
    def print_rho(self):
        print (self.new_rho)

rho = Density(10,20) # phi = 10, theta = 20
rho.print_rho()

3 Comments

No, your example is wrong. It will make sure Pixel is executed every time Density __init__ is called.
@hruske Indeed. As I said after each instantiate they will be created. And there is no need to call the constructor of an object multiple time, once it gets created.
Albert asked how to load data only once for many Density objects. Your example will load data every time a Density object will be instantiated, which Albert intends to do in a loop. Which is the opposite of his intentions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.