在Python类中导入脚本中的模块

时间:2014-01-15 14:10:33

标签: python python-2.7

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

def foo(): print("foo")

如果我尝试将其导入第二个脚本,我会'找不到模块'

import first

first.foo()

ImportError: No module named first

其次,我编写了一个脚本,用于定义非线性回归的类。该脚本导入类中的模块。但是,我也需要导入类的OUTSIDE模块。如果未在类定义的内部和外部导入模块,则脚本将不起作用:

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

这些问题是相关的,因为我尝试将此类导入另一个脚本而我不能(如第一个问题)。谁能告诉我发生了什么事?

更新

我刚开始能够导入脚本。无论开始路径上什么样的时髦清洁似乎最终都被删除了。不知道那是什么。但是,我仍然不明白为什么,如果我在我的类定义中导入必要的模块,我必须在我的其他脚本中导入它们。在我看来,如果我的类导入模块,我也不需要全局导入它们。这是对的吗?

1 个答案:

答案 0 :(得分:1)

我认为zhangxaochen的第一个评论是问题编号1的最佳起始位置.sys.path应包含python在尝试导入模块时搜索的所有路径。这些是我要解决这个问题的步骤:

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

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

如果两者都结账......