Reputation: 1053
I am adding some code into an existing class for testing purposes. Normally this class, eigensystem_CUDA_implementation
, relies on some functions and attributes of its parent. When this class is imported independently of the rest of the program, I'd like to substitute the usual parent class for a testParent class.
If this is a bad way to test code and I should do this completely differently, I'm open to that suggestion.
When initializing an eigensystem_CUDA_implementation
object, the error is:
NameError: free variable 'np' referenced before assignment in enclosing scope
which traces back to the line self.mat = np.matrix(...
There is much more that relies on NumPy and pyCUDA in eigensystem_CUDA_implementation
that is not shown. Can a class import a module that it relies on? Haven't tested this yet because of the first error.
class eigensystem_CUDA_implementation:
def __init__(self, parent = None, max_time = 60, delta = 10**(-32)):
# For testing purposes, when class is utilized independently
if(not parent):
# testing mode
if(not sys.modules.has_key("numpy")):
import numpy as np
import pycuda.driver as cuda
import pycuda.autoinit
from pycuda.compiler import SourceModule
class testParent:
def __init__(self, size = 10):
self.size = size
self.delta = 10**(-32)
self.num_site_types = 8
self.mat = np.matrix(np.random.random((self.size,self.size)).astype(np.float64))
def get_mutation_selection_matrix(self, alpha):
return self.mat
...
One potential problem: not sys.modules.has_key("numpy")
would show NumPy as imported whether it is named "np" or something else. The rest of the code uses "np" though so I'm ignoring this.
Thanks for any suggestions
Upvotes: 2
Views: 6508
Reputation: 251353
Your code will fail if numpy is already imported. You only import it inside the if
block, so if it's already imported it won't be defined inside that block. But later in the same function you reference np
as a local variable.
Anyway, you don't really need to worry about importing numpy. Just do import numpy as np
unconditionally. If it's already imported, it will just re-use the imported version. It won't waste memory or anything importing it twice.
That said, this code looks rather unwieldy and fragile. You should see if there's a better way to do this, by for instance defining a separate function that patches up the class with the necessary attributes. Having a class and an import inside a method inside another class is getting pretty hairy.
Upvotes: 3
Reputation: 104712
When you put an import within a function, like you're doing in __init__
, the variable that the module gets assigned to is local to that function. If you want it to be a global variable, you need to make it one explicitly with a global
statement. global np, cuda, SourceModule
may do it.
Also, it may not be enough to check for numpy
in sys.modules
before using np
, as numpy could have been imported by a different module, rather than the current one. You could check np in locals()
, but it might be easier to simply do the imports unconditionally.
Upvotes: 1