Python中如何让父类方法返回自定义子类实例
自定义继承gtfs-kit Feed类时父类方法返回父类实例的解决方法
问题原因
gtfs-kit原生Feed类中所有返回新实例的方法,都硬编码指定返回gk.feed.Feed类型,没有使用self.__class__动态匹配当前调用实例的所属类,因此子类调用这些方法时,不会自动返回子类实例。
现有代码参考
自定义子类初始定义
import gtfs_kit as gk class Feed(gk.feed.Feed): def __init__(self, **kwargs): super().__init__(**kwargs)
问题复现流程
import gtfs_kit as gk from .gtfs import Feed data_folder = 'data/' # 读取GTFS文件,得到原生Feed实例 feed = gk.read_feed(data_folder +'gtfs.zip', dist_units='km') # 手动转换为自定义Feed实例 feed_dict = {table: getattr(feed, table) for table in gk.cs.GTFS_REF["table"]} feed_dict['dist_units'] = feed.dist_units feed = Feed(**feed_dict) # 调用父类方法后,返回值回退为原生Feed实例 feed = feed.append_dist_to_shapes()
可行解决方案
方案1:类内统一拦截返回值,自动转换类型
在自定义类中通过__getattribute__拦截所有方法调用,只要方法返回原生Feed实例,就自动转换为当前自定义类实例,不需要逐个重写父类方法,一次配置覆盖所有同类方法:
import gtfs_kit as gk class Feed(gk.feed.Feed): def __init__(self, **kwargs): super().__init__(**kwargs) def __getattribute__(self, name): attr = super().__getattribute__(name) if not callable(attr): return attr def wrapped_method(*args, **kwargs): res = attr(*args, **kwargs) # 仅转换原生Feed类型的返回值 if type(res) is gk.feed.Feed: feed_attrs = { table: getattr(res, table) for table in gk.cs.GTFS_REF["table"] } feed_attrs["dist_units"] = res.dist_units return self.__class__(**feed_attrs) return res return wrapped_method # 在此处新增你的自定义方法即可
- 优势:对gtfs-kit库本身无侵入,不影响库内其他逻辑,后续父类新增的返回实例的方法也能自动适配。
方案2:猴子补丁全局替换原生Feed类
如果希望gk.read_feed()等库方法直接返回自定义Feed实例,不需要手动做类型转换,可以在导入gtfs-kit后直接替换库内的Feed类引用:
import gtfs_kit as gk class Feed(gk.feed.Feed): def __init__(self, **kwargs): super().__init__(**kwargs) # 在此处新增你的自定义方法 # 全局替换gtfs-kit内的Feed类引用 gk.feed.Feed = Feed gk.Feed = Feed
- 注意:如果项目中其他模块依赖原生gtfs-kit Feed类的独立行为,不建议使用该方案,避免引发非预期冲突。
内容的提问来源于stack exchange,提问作者Simon Fortin
相关产品推荐
相关产品推荐

