在Python类的脚本中导入模块
我在尝试定义自己的类时遇到了两个问题。首先,最基本的问题是,如果我编写一个python脚本并尝试将其导入到第二个脚本中,则导入失败(脚本位于同一目录中)。例如,我编写了一个名为first.py的脚本:在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 其次,我编写了一个脚本,为非线性回归定义了一个类。脚本导入类中的
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,看起来它已经被修复了。