Python类内启动线程触发TypeError:需2个参数却传入3个
Python类中启动线程触发TypeError问题
我在Python类中从内部函数启动线程时触发TypeError,提示"takes 2 positional args but 3 were given"。我尝试在最后一个参数后添加逗号但无效果,以下是相关代码片段及可复现代码,请问我哪里出错了?
代码片段
def tfunc(this.args.dir, folder): for file in os.listdir(folder): this.executeFile(os.path.join(this.args.dir, file)) def executeFiles(this): for folders1 in os.listdir(this.args.dir): for folders2 in os.listdir("downloaded/" + os.path.join(folders1)): t = threading.Thread(target=this.tfunc, args=(this, folders2)) t.start()
可复现代码
import os import sys import time import csv import argparse import threading class MoodysParser : def complete(this) : print(f"Complete") exit() def executeFile(this, filename): print(filename) def tfunc(dir, folder): for file in os.listdir(folder): this.executeFile(os.path.join(dir, file)) def executeFiles(this): for folders1 in os.listdir(this.args.dir): for folders2 in os.listdir("downloaded/" + os.path.join(folders1)): t = threading.Thread(target=this.tfunc, args=(this.args.dir, folders2)) t.start() def execute(this) : sys.setrecursionlimit(10000) this.timestamp = int(time.time()); this.dir = os.path.dirname(__file__); this.out_fn = f"moodys-results-{this.timestamp}.csv"; this.file_x = 1 this.fields_template = {}; this.fields_template["company"] = ""; this.fields_template["telephone"] = ""; this.fields_template["address"] = ""; this.fields_template["telephone2"] = ""; this.fields_template["link_id"] = ""; this.fields_template["location_type"] = ""; this.fields_template["industry"] = ""; this.fields_template["sales_range"] = ""; this.fields_template["employees"] = ""; this.fields_template["alerts_risk_increase"] = ""; this.fields_template["alerts_overall_payments"] = ""; this.fields_template["alerts_peer_payments"] = ""; this.fields_template["alerts_bankruptcy"] = ""; this.fields_template["alerts_tax_liens"] = ""; this.fields_template["alerts_financial_news"] = ""; this.fields_template["alerts_ucc_filings"] = ""; this.fields_template["number_reviews"] = ""; this.fields_template["average_rating"] = ""; this.fields_template["reviews"] = ""; this.firstrun = not os.path.isfile(this.out_fn) this.out = open(this.out_fn, 'w', newline='', encoding="utf8"); print(f"Opening {this.out_fn}"); this.writer = csv.writer(this.out, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL); this.out.write(b'\xEF\xBB\xBF'.decode()) this.writer.writerow(this.fields_template.keys()); parser = argparse.ArgumentParser() parser.add_argument('--dir', type=str, required=True); parser.add_argument('--max', type=int); parser.add_argument('--debug', action=argparse.BooleanOptionalAction); this.args = parser.parse_args(); if not os.path.isdir(this.args.dir): print(f"Input directory does not exist") exit() this.executeFiles() this.complete(); scraper = MoodysParser(); scraper.execute();
问题原因及修复方案
核心错误
MoodysParser类中的tfunc方法定义不符合Python类成员方法规范——它没有将实例引用(你代码里用this代替常规的self)作为第一个参数。
错误原理
当通过this.tfunc将类方法作为线程目标时,Python会自动把当前类实例this作为第一个参数传递给tfunc。而你在threading.Thread的args参数里又传入了this.args.dir和folders2两个参数,最终tfunc会收到三个参数(this、this.args.dir、folders2),但你的tfunc定义只接受两个参数,因此触发TypeError。
修复步骤
- 修改
tfunc的定义,将this作为第一个参数,后续再接收业务参数dir和folder - 保持
threading.Thread的args参数为(this.args.dir, folders2)即可(无需额外传入this)
修正后的代码片段
def tfunc(this, dir, folder): for file in os.listdir(folder): this.executeFile(os.path.join(dir, file)) def executeFiles(this): for folders1 in os.listdir(this.args.dir): # 修正路径拼接方式,保证跨平台兼容性 for folders2 in os.listdir(os.path.join("downloaded", folders1)): t = threading.Thread(target=this.tfunc, args=(this.args.dir, folders2)) t.start()
另外补充:原代码中路径拼接"downloaded/" + os.path.join(folders1)容易出现格式错误,建议改用os.path.join("downloaded", folders1)来保证跨平台的路径正确性。
内容的提问来源于stack exchange,提问作者D. W
相关产品推荐
相关产品推荐

