Python类中如何将带固定参数的方法赋值给变量?
问题描述
现有File类基于trashUntrash方法用lambda实现了多个包装方法,但参数较多时lambda语句过于冗长。尝试直接赋值带预设参数的方法时触发NameError,想了解在Python 3.10.8中,如何在类内将带指定预设参数的方法赋值为变量。
原代码如下:
class File(): def __init__(self): self.this = this self.that = that def trashUntrash(self, fileId, bool): return file.update(fileId, isTrashed=bool) # 基于trashUntrash的包装lambda trash = lambda self, fileId: self.trashUntrash(fileId, True) untrash = lambda self, fileId: self.trashUntrash(fileId, False) # 其他对应不同方法的lambda fileTitle = lambda self, id: self.fileInfo(prop="title", spreadsheetId=id) fileIds = lambda self, id: self.fileInfo(prop="fileId", spreadsheetId=id) addPage = lambda self, id, title: self.action(i=0, ssId=id, title=title) delPage = lambda self, id, pageId: self.action(i=1, ssId=id, pageId=pageId) renameFile = lambda self, id, pageId, title: self.action(i=2, id=id ...)
尝试直接赋值时出现报错:
# 报错:NameError: name 'self' is not defined trash = self.trashUntrash(fileId, True) untrash = self.trashUntrash(fileId, False)
解决方案
方法1:用functools.partial/partialmethod预设参数
functools提供的partial和partialmethod可以固定函数的部分参数,替代冗长的lambda,同时解决self绑定问题。
方式A:在__init__中用partial初始化实例绑定方法
这种方式会为每个实例创建绑定后的方法,逻辑清晰:
from functools import partial class File(): def __init__(self): self.this = this self.that = that # 预设trashUntrash的第二个参数 self.trash = partial(self.trashUntrash, bool=True) self.untrash = partial(self.trashUntrash, bool=False) # 预设fileInfo的prop参数 self.fileTitle = partial(self.fileInfo, prop="title") self.fileIds = partial(self.fileInfo, prop="fileId") # 预设action的i参数 self.addPage = partial(self.action, i=0) self.delPage = partial(self.action, i=1) self.renameFile = partial(self.action, i=2) def trashUntrash(self, fileId, bool): return file.update(fileId, isTrashed=bool) def fileInfo(self, prop, spreadsheetId): # 业务逻辑实现 pass def action(self, i, **kwargs): # 业务逻辑实现 pass
调用时只需传入剩余参数:
f = File() f.trash("file_123") # 等价于f.trashUntrash("file_123", True) f.fileTitle("sheet_456") # 等价于f.fileInfo("title", "sheet_456")
方式B:用partialmethod定义类级别的包装方法
partialmethod专门用于类方法的参数绑定,无需在__init__中初始化,直接作为类属性存在:
from functools import partialmethod class File(): def __init__(self): self.this = this self.that = that def trashUntrash(self, fileId, bool): return file.update(fileId, isTrashed=bool) # 用partialmethod固定参数 trash = partialmethod(trashUntrash, bool=True) untrash = partialmethod(trashUntrash, bool=False) def fileInfo(self, prop, spreadsheetId): pass fileTitle = partialmethod(fileInfo, prop="title") fileIds = partialmethod(fileInfo, prop="fileId") def action(self, i, **kwargs): pass addPage = partialmethod(action, i=0) delPage = partialmethod(action, i=1) renameFile = partialmethod(action, i=2)
方法2:用普通def定义包装方法
如果不想依赖functools,直接用普通函数定义包装方法,可读性更强,调试维护更方便:
class File(): def __init__(self): self.this = this self.that = that def trashUntrash(self, fileId, bool): return file.update(fileId, isTrashed=bool) def trash(self, fileId): return self.trashUntrash(fileId, True) def untrash(self, fileId): return self.trashUntrash(fileId, False) def fileInfo(self, prop, spreadsheetId): pass def fileTitle(self, id): return self.fileInfo(prop="title", spreadsheetId=id) def fileIds(self, id): return self.fileInfo(prop="fileId", spreadsheetId=id) def action(self, i, **kwargs): pass def addPage(self, id, title): return self.action(i=0, ssId=id, title=title) def delPage(self, id, pageId): return self.action(i=1, ssId=id, pageId=pageId) def renameFile(self, id, pageId, title): return self.action(i=2, id=id, pageId=pageId, title=title)
直接赋值报错的原因
你尝试的trash = self.trashUntrash(fileId, True)是在类定义阶段执行的,此时self(实例对象)还未创建,fileId也没有定义,因此触发NameError。即使去掉self,fileId仍未定义,同样报错。而trash = self.trashUntrash也会因类定义阶段self不存在而失败。
内容的提问来源于stack exchange,提问作者Alejandro
相关产品推荐
相关产品推荐

