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

Python如何完整包装无法直接实例化的C++扩展类(如htcondor.JobEvent)

解决方案

你要实现的需求可以通过「组合代理+虚拟子类注册」的方式实现,完全符合Python开发规范,不需要依赖第三方库,也不用硬编码所有方法的转发逻辑:

核心思路

  1. 不直接继承htcondor.JobEvent,避免触发C++转译类的实例化限制
  2. 通过虚拟子类注册让isinstance(包装类实例, htcondor.JobEvent)返回True,满足所有类型校验要求
  3. 自动批量转发所有魔法方法,补全__getattr__无法处理魔法方法的缺陷

完整实现代码

import htcondor
from datetime import datetime
import json

STRP_FORMAT = "%Y-%m-%d %H:%M:%S" # 替换为你实际使用的时间解析格式

# 定义需要自动转发的魔法方法,覆盖类字典对象的所有常用操作
MAGIC_METHODS_TO_FORWARD = [
    "__getitem__", "__setitem__", "__delitem__", "__contains__",
    "__len__", "__iter__", "__str__"
]

class HTCJobEventWrapper:
    """
    HTCondor JobEvent的包装类
    自动提取事件编号和时间戳,支持直接打印用于开发调试
    :param job_event: 原生HTCondor JobEvent实例
    """
    def __init__(self, job_event: htcondor.JobEvent):
        self._wrapped = job_event
        self.event_number = job_event.get('EventTypeNumber')
        self.time_stamp = datetime.strptime(
                job_event.get('EventTime'),
                STRP_FORMAT
            )
    
    # 所有普通属性、方法都走这个逻辑自动转发
    def __getattr__(self, attr):
        return getattr(self._wrapped, attr)
    
    # 自动生成魔法方法的转发函数
    @classmethod
    def _generate_magic_forwarder(cls, method_name):
        def forwarder(self, *args, **kwargs):
            return getattr(self._wrapped, method_name)(*args, **kwargs)
        forwarder.__name__ = method_name
        setattr(cls, method_name, forwarder)
    
    # 自定义功能
    def to_dict(self):
        """将事件内容转为标准Python字典"""
        return dict(self.items())

    def __repr__(self):
        return json.dumps(
            self.to_dict(),
            indent=2,
            ensure_ascii=False
        )

# 批量注册需要转发的魔法方法
for method in MAGIC_METHODS_TO_FORWARD:
    HTCJobEventWrapper._generate_magic_forwarder(method)

# 注册为htcondor.JobEvent的虚拟子类,解决类型判断问题
htcondor.JobEvent.register(HTCJobEventWrapper)

效果验证

# event 是你从接口获取的原生htcondor.JobEvent实例
wrapped_event = HTCJobEventWrapper(event)

# 类型校验完全通过
print(isinstance(wrapped_event, htcondor.JobEvent)) # 输出 True

# 所有原生属性、方法都可以正常调用,和原生实例行为完全一致
print(wrapped_event.get("EventTime"))
print(wrapped_event["EventTypeNumber"])
print(len(wrapped_event))

# 自定义属性、方法正常使用
print(wrapped_event.event_number)
print(wrapped_event.time_stamp)
print(wrapped_event.to_dict())

常见问题说明

你之前使用__getattr__只能转发普通属性,是因为Python的魔法方法(前后带双下划线的特殊方法)不会走__getattr__的转发逻辑,解释器会直接在类的定义中查找对应的方法,所以只要把你需要用到的魔法方法加到转发列表里批量生成即可,不需要手动逐个实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:06:02