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

OptaPy Python版isEqual语法使用及get_id调用TypeError报错咨询

问题原因

你触发的TypeError: get_id() missing 1 required positional argument: 'self'错误,是因为在Joiners.equal()中直接调用了实例方法Timeslot.get_id():实例方法必须绑定到具体对象才能调用,你直接写带括号的get_id()属于未绑定调用,缺少实例参数self。
OptaPy的Joiners.equal()接收的是字段访问器函数,不需要你主动调用方法,只需要传入方法引用或者lambda表达式即可。

修正方案

方案1(无需修改Domain代码)

直接在Joiner中使用lambda表达式取值,调整constraints.py代码如下:

import datetime
from optapy.score import HardSoftScore
from optapy.constraint import Joiners
# 替换为你实际的domain导入路径
from domain import Timeslot, Match

def fill_pitches_from_start(constraint_factory):
    # 场地应尽可能不闲置,优先排早时段
    return constraint_factory \
        .forEach(Timeslot) \
        .ifNotExists(Match, Joiners.equal(
            Timeslot.get_id, 
            lambda match: match.timeslot.id if match.timeslot is not None else None
        ))  \
        .join(Timeslot, 
              # 把时间比较挪到Join条件中,比事后filter效率更高
              Joiners.greaterThan(
                  lambda slot2: datetime.datetime.combine(
                      # 替换为你实际的date_str格式
                      datetime.datetime.strptime(slot2.date_str, '%Y-%m-%d').date(),
                      slot2.start_time
                  ), 
                  lambda slot1: datetime.datetime.combine(
                      datetime.datetime.strptime(slot1.date_str, '%Y-%m-%d').date(),
                      slot1.start_time
                  )
              )
        ) \
        .ifExists(Match, Joiners.equal(
            lambda slot2: slot2.get_id(), 
            lambda match: match.timeslot.id if match.timeslot is not None else None
        )) \
        .penalize("Pitch Empty with Later pitches populated", HardSoftScore.ofSoft(10))

如果你的OptaPy版本较低不支持forEach,将其替换为旧版写法from_即可。

方案2(修改Domain代码简化约束写法)

先给Match类补充返回关联时段ID的方法:

@planning_entity
class Match:
    # 保留你原有的__init__、规划变量定义等代码
    def get_timeslot_id(self):
        return self.timeslot.id if self.timeslot else None

之后约束中的Joiner可以直接传方法引用,更简洁:

Joiners.equal(Timeslot.get_id, Match.get_timeslot_id)
关键改动说明
  • 所有Joiners.equal中传入的方法都去掉了括号,直接传方法引用Timeslot.get_id,OptaPy会自动把匹配到的实例传入方法获取对应值
  • 修正了Match和Timeslot的匹配逻辑:直接取Match关联时段的ID和Timeslot的ID做等值匹配,避免类型不一致问题
  • 补充了字符串日期转date对象的逻辑,适配datetime.combine的参数要求,可根据你实际的date_str格式调整解析模板
  • 修正了原代码中slot1.timeslot.start_time的错误写法:slot1本身就是Timeslot实例,不需要再取.timeslot属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:24:03