为何使用str.endswith("mp4")作为filter参数会触发参数错误?
问题解析:str.endswith在filter中传参失效的原因
问题重现
运行以下代码时触发错误:
filtered_list = list(filter(str.endswith("mp4"), my_files))
报错信息:
TypeError: endswith() takes at least 1 argument (0 given)
失效原因
核心问题出在类方法的绑定逻辑:
str.endswith是字符串类的未绑定方法,正常调用时需要两个关键参数:第一个是字符串实例(self,也就是要检查的目标字符串),第二个是要匹配的后缀。- 你写
str.endswith("mp4")时,相当于直接调用这个类方法,但只传了后缀参数,没传必要的self实例,这时候这个调用本身就不合法,更不会返回一个能被filter使用的可调用函数。当filter尝试遍历my_files并调用这个“返回值”时,实际上是在调用一个缺少self参数的方法,自然会报“参数不足”的错误。
类.方法写法能不能传参?
不是完全不能,而是不能直接这么传。要让类方法带上预设参数供filter使用,需要通过参数绑定的方式,比如用functools.partial:
from functools import partial filtered_list = list(filter(partial(str.endswith, suffix="mp4"), my_files))
partial会帮你把"mp4"作为suffix参数预先绑定到str.endswith上,当filter处理my_files中的每个字符串时,会自动把字符串作为self参数传入,满足方法的调用要求。
常见可行替代方案
你提到的两种方式都是正确的思路,这里再明确写法:
- Lambda函数:
filtered_list = list(filter(lambda x: x.endswith("mp4"), my_files))
这里lambda会接收my_files中的每个字符串x,然后调用它的endswith方法并传入"mp4",逻辑清晰直接。
operator.methodcaller:
from operator import methodcaller filtered_list = list(filter(methodcaller("endswith", "mp4"), my_files))
methodcaller会创建一个可调用对象,它会接收目标实例,然后调用指定的方法并传入预设参数,本质也是帮你处理了参数绑定的问题。
内容的提问来源于stack exchange,提问作者Maria
相关产品推荐
相关产品推荐

