当创建一个新的类实例时,我试图在另一个类中调用一个方法,但无法使其工作。以下是我所拥有的:
class DataProject(object):
def __init__(self, name=none,input_file=None,datamode=None,comments=None,readnow=True):
..............
# here's where I'm trying to call the method in the other class
if type(input_file) == str:
self.input_file_format = self.input_file.split(".")[-1]
if readnow:
getattr(Analysis(),'read_'+self.input_file_format)(self,input_file)
class Analysis(object):
def __init__(self):
pass # nothing happens here atm
def read_xlsx(self,parent,input_file):
"""Method to parse xlsx files and dump them into a DataFrame"""
xl = pd.ExcelFile(input_file)
for s in sheet_names:
parent.data[s]=xl.parse(s)
当我用运行这个时,我得到一个NameError: global name 'read_xlsx' is not defined
文件.xlxs作为输入,我认为我刚刚发现了我的Python知识中的一个巨大漏洞(不是说没有多少,但它们往往很难看到,有点像大森林……)。在
我本以为getattr(Analysis(), ... )
将访问全局名称空间,在该空间中它将找到分析类及其方法。事实上,print(globals().keys())
表明分析是其中的一部分:
['plt', 'mlab', '__builtins__', '__file__', 'pylab', 'DataProject', 'matplotlib', '__package__', 'W32', 'Helpers', 'time', 'pd', 'pyplot', 'np', '__name__', 'dt', 'Analysis', '__doc__']
我错过了什么?在
编辑:
完整的回溯是:
^{pr2}$我的主要任务是:
if __name__=="__main__":
a=DataProject(input_file='C:\\MPython\\dataAnalysis\\EnergyAnalysis\\afile.xlx',readnow=True)
getattr()
的工作原理与您在Python2.x和Python3.x中描述的一样。bug一定在其他地方。在对代码的这种修改(核心逻辑都没有更改)可以正常工作,例如:
输出为:
^{pr2}$为什么以这种方式使用
getattr()
通常是个坏主意您使用
getattr
的方式迫使您的方法(read_someformat
)有一个命名约定。方法的命名不应该是程序逻辑的核心部分。-您应该始终能够在每次调用时更改函数的名称和该函数的定义,并保持程序的行为不变。在如果一个文件格式需要用一种特定的方法来处理,那么这个逻辑应该被委托给某个负责这个问题的单位(例如一个职能部门)。实现这一点的一种方法是让一个接受输入并决定哪个函数需要处理它的函数:
上面的代码片段也有它的问题(例如,chain of responsibility pattern是一个更好的方法),但是对于小脚本来说它是可以的,并且更好。在
从完整的回溯来看,
DataProject
类似乎正在(成功地)调用Analysys.read_xls
方法,而该方法又在尝试调用read_xlsx
。但是,它将其作为全局函数调用,而不是作为方法调用。在可能您只需要替换第90行的代码,将
read_xlsx(input_file)
转换为self.read_xlsx(input_file)
,尽管您可能还需要为父DataProject
实例传递一个额外的参数。在相关问题 更多 >
编程相关推荐