Python:在封闭scop中赋值之前引用了自由变量“numpy”

2024-10-01 11:23:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在将一些代码添加到现有类中以进行测试。通常这个类eigensystem_CUDA_implementation,依赖于其父类的一些函数和属性。当这个类独立于程序的其余部分导入时,我想用通常的父类替换testParent类。在

如果这是一种不好的测试代码的方法,而且我应该完全不同,我愿意接受这个建议。在

初始化eigensystem_CUDA_implementation对象时,错误为:

NameError: free variable 'np' referenced before assignment in enclosing scope

它可以追溯到self.mat = np.matrix(...

eigensystem_CUDA_implementation中有更多依赖于NumPy和pyCUDA的东西没有显示出来。类可以导入它所依赖的模块吗?由于第一个错误,还没有对此进行测试。在

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
    ...

一个潜在的问题是:not sys.modules.has_key("numpy")会将NumPy显示为导入的,无论它是命名为“np”还是其他名称。其余的代码使用了“np”,所以我忽略了这一点。在

谢谢你的建议


Tags: 代码importselfpycudanumpysizedefnp
2条回答

如果numpy已经导入,您的代码将失败。您只在if块中导入它,因此如果它已经导入,则不会在该块中定义它。但稍后在同一个函数中,您将np作为局部变量引用。在

不管怎样,你不必担心进口纽比。无条件地做import numpy as np。如果它已经导入,它只会重用导入的版本。它不会浪费内存或任何东西两次导入它。在

也就是说,这段代码看起来相当笨拙和脆弱。您应该看看是否有更好的方法来实现这一点,例如定义一个单独的函数,用必要的属性修补类。在另一个类中的方法中拥有一个类和一个导入是非常困难的。在

当您将导入放入函数中时,就像您在__init__中所做的那样,模块分配给的变量是该函数的本地变量。如果希望它成为全局变量,则需要使用global语句显式地将其设为全局变量。global np, cuda, SourceModule可以做到。在

另外,在使用np之前检查numpy中的numpy可能还不够,因为numpy可能是由其他模块而不是当前模块导入的。您可以检查np in locals(),但更简单的方法是无条件地进行导入。在

相关问题 更多 >