我有一个列表,我将使用文件作为示例。需要以不同的方式处理每种类型的文件。我创建了一个类“MyFile”而不是维护一个巨大的if:elif:else:structure我创建了一个以文件类型为键的字典。它存储为类变量。
class MyFile(object):
def process_xlsx(self):
#process file stuff for Excel
pass
def process_docx(self):
#process file stuff for Word
pass
def get_filetype(self):
try:
return self.FileTypes[file_extension]
except KeyError:
return None #filetype not handled... yet
FileTypes = {
"XLSX": ("Excel File", process_xlsx),
"DOCX": ("Word Document", process_docx)
}
在不同的类/对象/模块中,我实例化MyFile类并开始逐步执行文件。 MyFile对象已正确创建。
f = MyFile("full_file_path_and_name")
file_type = f.get_filetype()
file_type有一个带有键的元组和一个函数对象。这是一个例子: xls_0386.xlsx - ('Excel文件',) doc_0386.docx - ('Word File',)
问题:如何调用从f.get_filetype()返回的函数?
file_type[1]()
返回:process_xlsx()缺少1个必需的位置参数:'self'
file_type[1]
不会创建错误,但实际上从不进行调用(在进程_ ????方法中永远不会达到断点)
再次,以这种方式调用对象方法的语法是什么?
我知道用我的细节解释这有点令人费解,为此我道歉。
提前致谢。
答案 0 :(得分:1)
创建class
时,您在其中定义的方法是只是函数。只有当您从类的实例中检索它们的名称时,它们才会绑定到该实例,从而生成绑定方法。这是通过descriptor protocol完成的。
因此,当您创建FileTypes
词典时:
FileTypes = {
"XLSX": ("Excel File", process_xlsx),
"DOCX": ("Word Document", process_docx)
}
这些是普通的功能。
您有三种选择,基本上:
不要在课程定义时创建字典。在创建实例时创建它,以便可以在其中存储绑定方法:
class MyFile(object):
def __init__(self):
self.FileTypes = {
"XLSX": ("Excel File", self.process_xlsx),
"DOCX": ("Word Document", self.process_docx)
}
因为这会查找self
上的方法,所以它们是绑定的。
手动绑定方法'当你在get_filetype()
中查找时:
def get_filetype(self):
try:
return self.FileTypes[file_extension].__get__(self) # binding!
except KeyError:
return None #filetype not handled... yet
返回functools.partial()
object self
作为位置参数而不仅仅是函数:
from functools import partial
def get_filetype(self):
try:
return partial(self.FileTypes[file_extension], self) # also a kind of binding
except KeyError:
return None #filetype not handled... yet
所有这三种方法都会导致一个对象被返回给调用者,当被调用时,它会将MyFile()
的正确实例传递给所选择的函数。
答案 1 :(得分:0)
你用第一个参数调用它是你想要的自己。例如:
f = MyFile("full_file_path_and_name")
file_type = f.get_filetype()
file_type[1](f)
这样,您还可以使用该功能的任何其他文件。如果您只想使用file_type[1]
调用特定文件,请使用部分填充的函数,因此self
已经是参数。您可以使用functools.partial
import functools
class MyFile(object):
# ...
def get_filetype(self):
def partial(func):
return functools.partial(func, self)
return {"XLSX": ("Excel File", partial(process_xlsx)),
"DOCX": ("Word Document", partial(process_docx))
}.get(self.file_extension)
# Then you just do
f = MyFile("full_file_path_and_name")
file_type = f.get_filetype()
file_type[1]()
答案 2 :(得分:0)
因为这些函数是在类中声明的,所以它们具有参数self
,表示该类中调用该函数的对象。当您尝试单独调用该函数时,在MyFile
对象的上下文之外,不再有self
变量与函数调用关联。这就是你收到错误的原因:
缺少1个必要的位置参数:' self'
只需将您已创建的MyFile
实例作为self
变量使用:
file_type[1](f)