在Python类的脚本中导入模块

在Python类的脚本中导入模块,python,python-2.7,Python,Python 2.7,我在尝试定义自己的类时遇到了两个问题。首先,最基本的问题是,如果我编写一个python脚本并尝试将其导入到第二个脚本中,则导入失败(脚本位于同一目录中)。例如,我编写了一个名为first.py的脚本: def foo(): print("foo") 如果我尝试将其导入到第二个脚本中,我会得到“找不到模块” import first first.foo() ImportError: No module named first 其次,我编写了一个脚本,为非线性回归定义了一个类。脚本导入类中的

我在尝试定义自己的类时遇到了两个问题。首先,最基本的问题是,如果我编写一个python脚本并尝试将其导入到第二个脚本中,则导入失败(脚本位于同一目录中)。例如,我编写了一个名为first.py的脚本:

def foo(): print("foo")
如果我尝试将其导入到第二个脚本中,我会得到“找不到模块”

import first

first.foo()

ImportError: No module named first
其次,我编写了一个脚本,为非线性回归定义了一个类。脚本导入类中的模块。但是,我还需要导入类外的模块。如果未在类定义内部和外部导入模块,脚本将无法工作:

class NLS:
    ''' This provides a wrapper for scipy.optimize.leastsq to get the relevant output for nonlinear least squares.
    Although scipy provides curve_fit for that reason, curve_fit only returns parameter estimates and covariances.
    This wrapper returns numerous statistics and diagnostics'''
    # IMPORT THE MODULES THE FIRST TIME - WILL NOT RUN WITHOUT THESE
    import numpy as np
    from scipy.optimize import leastsq 
    import scipy.stats as spst


    def __init__(self, func, p0, xdata, ydata):

         # Check the data
        if len(xdata) != len(ydata):
            msg = 'The number of observations does not match the number of rows for the predictors'
            raise ValueError(msg)

        # Check parameter estimates
        if type(p0) != dict:
            msg = "Initial parameter estimates (p0) must be a dictionry of form p0={'a':1, 'b':2, etc}"
            raise ValueError(msg)

        self.func = func
        self.inits = p0.values()
        self.xdata = xdata
        self.ydata = ydata
        self.nobs = len( ydata )
        self.nparm= len( self.inits )

        self.parmNames = p0.keys()

        for i in range( len(self.parmNames) ):
            if len(self.parmNames[i]) > 5:
                self.parmNames[i] = self.parmNames[i][0:4]

        # Run the model
        self.mod1 = leastsq(self.func, self.inits, args = (self.xdata, self.ydata), full_output=1)

        # Get the parameters
        self.parmEsts = np.round( self.mod1[0], 4 )

        # Get the Error variance and standard deviation
        self.RSS = np.sum( self.mod1[2]['fvec']**2 )
        self.df = self.nobs - self.nparm
        self.MSE = self.RSS / self.df
        self.RMSE = np.sqrt( self.MSE )

        # Get the covariance matrix
        self.cov = self.MSE * self.mod1[1]

        # Get parameter standard errors
        self.parmSE = np.diag( np.sqrt( self.cov ) )

        # Calculate the t-values
        self.tvals = self.parmEsts/self.parmSE

        # Get p-values
        self.pvals = (1 - spst.t.cdf( np.abs(self.tvals), self.df))*2

        # Get biased variance (MLE) and calculate log-likehood
        self.s2b = self.RSS / self.nobs
        self.logLik = -self.nobs/2 * np.log(2*np.pi) - self.nobs/2 * np.log(self.s2b) - 1/(2*self.s2b) * self.RSS

        del(self.mod1)
        del(self.s2b)
        del(self.inits)        

    # Get AIC. Add 1 to the df to account for estimation of standard error
    def AIC(self, k=2):
        return -2*self.logLik + k*(self.nparm + 1)

    del(np)
    del(leastsq)

    # Print the summary
    def summary(self):
        print
        print 'Non-linear least squares'
        print 'Model: ' + self.func.func_name
        print 'Parameters:'
        print "               Estimate      Std. Error      t-value      P(>|t|)"
        for i in range( len(self.parmNames) ):
            print "%   -5s          % 5.4f       % 5.4f         % 5.4f      % 5.4f" % tuple( [self.parmNames[i], self.parmEsts[i], self.parmSE[i], self.tvals[i], self.pvals[i]] )                
        print
        print 'Residual Standard Error: % 5.4f' % self.RMSE
        print 'Df: %i' % self.df


## EXAMPLE USAGE
import pandas as pd
# IMPORT THE MODULES A SECOND TIME. WILL NOT RUN WITHOUT THESE
import numpy as np
from scipy.optimize import leastsq 
import scipy.stats as spst

# Import data into dataframe
respData = pd.read_csv('/Users/Nate/Documents/FIU/Research/MTE_Urchins/Data/respiration.csv')

# Standardize to 24 h
respData['respDaily'] = respData['C_Resp_Mass'] * 24

# Create the Arrhenius temperature
respData['Ar'] = -1 / (8.617 * 10**-5 * (respData['Temp']+273))

# Define the likelihood null model
def nullMod(params, mass, yObs):
    a = params[0]
    c = params[1]    
    yHat = a*mass**c
    err = yObs - yHat
    return(err)


p0 = {'a':1, 'b':1}

tMod = NLS(nullMod, p0, respData['UrchinMass'], respData['respDaily'] )

tMod.summary()

tMod.AIC()

tMod.logLik
这些问题是相关的,因为我试图将这个类导入到另一个脚本中,但我不能(如第一个问题中所示)。谁能告诉我发生了什么事

更新


我刚开始能够导入脚本。不管是什么样的开始路径,看起来最终都被删除了。不知道那是什么。然而,我仍然不明白为什么,如果我在我的类定义中导入必要的模块,那么我还必须在我的其他脚本中导入它们。在我看来,如果我的类导入模块,我就不需要全局导入它们。这是正确的吗?

我认为张晓晨的第一句话是第一道题的最佳出发点。sys.path应该包含python在尝试导入模块时搜索的所有路径。以下是解决这个问题的步骤:

确保os.getcwd()返回与os.path.dirname(sys.argv[0])相同的目录

接下来,我要确保该路径位于sys.path列表中


如果这两个都签了

first.py
是否与当前脚本位于同一文件夹中,或者它在
sys.path
列表中的路径?如果只导入脚本顶部的类定义之前的
numpy
scipy
会怎么样。还有,为什么你有
del(np)”和
del(leastsq)`;这似乎真的很奇怪。至于你问题的第一部分:这对我来说很好。您显示的这些行实际上是测试脚本中唯一的代码行?您可以从Python命令行(仍在同一目录中)导入
first
?是的,测试脚本中的这些行确实是唯一的行。另外,first.py与当前脚本位于同一文件夹中。我不能先从命令行导入,但我不知道如何将目录设置到桌面。将导入命令移到脚本顶部仍然会导致错误OK我尝试了第一次诊断,确保os.getswd()与os.path.dirname()是同一目录。不是。os.getcwd()返回:/Users/Nate/Desktop,而os.path.dirname(sys.argv[0])返回:/private/var/folders/zl/yxc7hlld61b6y2n5ghnn_q4h0000gn/T/Cleanup启动时。第二个文件夹到底是什么?第一个是(两个)脚本的目录。当我尝试sys.path时,第二个奇怪的文件路径在列表中,但我的桌面不是。@Nate好的,这很奇怪。您能否在终端cmdline上检查以下命令:
which python
然后
ls-l`which python`
?您运行的python好像有一个指向某个非常奇怪的文件的符号链接。顺便说一句,
sys.path
可能包含一个空字符串
'
作为第一个元素,它指示您当前的目录,即您的案例中的桌面。所以,如果桌面没有列出,它可能仍然存在。嗯,真的很奇怪!不知道为什么会将其作为sys.argv[0]获取。您是从ide还是在命令行上运行脚本?打印sys.path时,是否在目录列表中的/Users/Nate/Desktop?如果不是,那么添加它,然后尝试导入。我是从命令行运行它的。从那以后我就开始工作了,但老实说,我不知道怎么做。我刚刚打开和关闭了python,看起来它已经被修复了。