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

Python作业调度回溯求解器报错:AttributeError与TypeError求助

作业调度回溯求解器的两类错误修复方案

错误原因分析与修复

1. AttributeError: 'str' object has no attribute 'variables'

根本原因:类的实例方法必须将self作为第一个参数,但你在check_constraint方法中把self放在了第三个参数位置。调用实例方法时,Python会自动将当前实例作为第一个参数传入,导致参数错位:

  • 方法定义中的arg1实际接收了self实例
  • arg2接收了var1(字符串)
  • self接收了var2(字符串)
    于是访问self.variables时,self是字符串类型,自然没有variables属性。

修复代码:
调整check_constraint的参数顺序,把self放在首位:

def check_constraint(self, arg1, arg2, assignment) -> bool:
    if (arg1 not in assignment) or (arg2 not in assignment):
        return True
    constraint = self.constraints.constraints[arg1][arg2]
    if constraint[1] == 0:
        return assignment[arg2] >= assignment[arg1] + constraint[0]
    if constraint[1] == 1:
        return assignment[arg1] + constraint[0] <= assignment[arg2]
    if constraint[1] == 2:
        return (assignment[arg1] + constraint[0] <= assignment[arg2]) or (assignment[arg2] + constraint[0] <= assignment[arg1])

同时保持调用方式不变:

result = self.check_constraint(var1, var2, assignment)

2. TypeError: 参数数量不匹配

根本原因:你尝试手动传入self到check_constraint,但Python实例方法会自动传递self作为第一个参数,导致实际传入的参数数量比方法定义多1个。

修复方式:
删除调用时手动传入的self,保持调用为:

result = self.check_constraint(var1, var2, assignment)

同时确保方法定义的参数顺序正确(如上面的修复)。

其他需要修复的方法参数问题

你的代码中还有多个实例方法存在self参数位置错误的问题,一并修复:

removeDomains方法

原定义:

def removeDomains(new_assignment, var,self):

修复后:

def removeDomains(self, new_assignment, var):
    removeddomains = {}
    for var1 in self.constraints.constraints[var]:
        constraint = self.constraints.constraints[var][var1]
        if constraint[1] == 0:
            intervallo_da_rimuovere = range(1, new_assignment[var] + 1 - constraint[0])
            nuovo_dominio = list(self.variables[var1])
            nuovo_dominio = list(filter(lambda x: x not in intervallo_da_rimuovere, nuovo_dominio))
            self.variables[var1] = range(nuovo_dominio[0], nuovo_dominio[-1] + 1)
            removeddomains[var1] = intervallo_da_rimuovere
        if constraint[1] == 1 or constraint[1] == 2:
            intervallo_da_rimuovere = range(1, new_assignment[var] + 1 + constraint[0])
            nuovo_dominio = list(self.variables[var1])
            nuovo_dominio = list(filter(lambda x: x not in intervallo_da_rimuovere, nuovo_dominio))
            self.variables[var1] = range(nuovo_dominio[0], nuovo_dominio[-1] + 1)
            removeddomains[var1] = intervallo_da_rimuovere
    return removeddomains

调用时改为:

tmp = self.removeDomains(new_assignment, var)

putRemovedDomains方法

原定义:

def putRemovedDomains(tmp, var,self):

修复后:

def putRemovedDomains(self, tmp, var):
    for var1 in self.constraints.constraints[var]:
        lista1 = list(tmp[var1])
        lista2 = list(self.variables[var1])
        lista_unione = lista1 + lista2
        lista_unione.sort()
        self.variables[var1] = range(lista_unione[0], lista_unione[-1] + 1)

调用时改为:

self.putRemovedDomains(tmp, var)

backtracking_search方法调用

原代码中递归调用时手动传了self:

result = self.backtracking_search(self, new_assignment)

修复后:

result = self.backtracking_search(new_assignment)

额外潜在问题修复

  • checkAllconstraints中的循环错误:原代码for var1,var2 in self.constraints.constraints:会遍历字典的键,导致解包错误,应该遍历所有约束对:
def checkAllconstraints(self, assignment) -> bool:
    for var1 in self.constraints.constraints:
        for var2 in self.constraints.constraints[var1]:
            result = self.check_constraint(var1, var2, assignment)
            if not result:
                return False
    return True
  • __init__中的约束实例化:如果constraint类和当前类在同一文件,应该改为self.constraints = constraint(),而不是constrs.constraint()(除非constrs是导入的模块)。

内容的提问来源于stack exchange,提问作者Babboboncia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 00:50:53