You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。

修复步骤

  1. 修改tfunc的定义,将this作为第一个参数,后续再接收业务参数dir和folder
  2. 保持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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 03:05:18