问题描述
history(count, unit='1d', field='avg', security_list=None, df=True, skip_paused=False, fq='pre')
attribute_history(security, count, unit='1d',fields=['open', 'close', 'high', 'low', 'volume', 'money'],skip_paused=True, df=True, fq='pre')
get_price(security, start_date=None, end_date=None, frequency='daily', fields=None, skip_paused=False, fq='pre', count=None, panel=True)
这个三个取数据的函数,df/panel,skip_paused,fq参数出现的顺序不一样,能不能改成一致的呀?
解决方案
您好!您观察得非常仔细。确实,在 JoinQuant (聚宽) 平台中,history、attribute_history 和 get_price 这三个常用的数据获取函数在可选参数(如 df/panel, skip_paused, fq)的排列顺序上存在不一致的情况。
为什么会出现参数顺序不一致?
这种现象在很多大型且持续迭代的软件库或 API 中都很常见,主要原因包括:
- 历史遗留与向后兼容性:这三个函数可能是在平台发展的不同阶段由不同的开发者设计和引入的。为了保证早期用户的策略代码在平台升级后依然能够正常运行(即向后兼容),平台方通常不能轻易修改已有函数的参数顺序。一旦修改,那些依赖位置参数传参的老策略就会报错或获取到错误的数据。
- 函数侧重点不同:
history侧重于获取多个标的的单个字段。attribute_history侧重于获取单个标的的多个字段。get_price是最通用的,支持多标的、多字段以及时间段查询。
设计时的侧重点不同,导致了核心参数(如count,security)的位置不同,后续追加的可选参数也就顺势排在了后面,从而造成了整体顺序的差异。
官方能否改成一致的?
作为平台的使用者,我们无法直接修改底层 API。虽然统一参数顺序在强迫症看来非常完美,但考虑到破坏向后兼容性带来的巨大风险,官方通常不会去修改这些已经稳定运行多年的 API 签名。
最佳实践解决方案:使用关键字参数(Keyword Arguments)
在 Python 中,解决参数顺序不一致且参数众多的最佳方法是始终使用关键字参数来传递可选参数。这样不仅可以完全无视参数在 API 定义中的物理顺序,还能极大地提高代码的可读性。
强烈建议的调用方式示例:
# 1. 调用 history
h = history(count=5, unit='1d', field='close', security_list=['000001.XSHE'], df=True, skip_paused=False, fq='pre')
# 2. 调用 attribute_history
ah = attribute_history(security='000001.XSHE', count=5, unit='1d', fields=['open', 'close'], df=True, skip_paused=False, fq='pre')
# 3. 调用 get_price
p = get_price(security='000001.XSHE', count=5, frequency='daily', fields=['open', 'close'], panel=False, skip_paused=False, fq='pre')
使用关键字参数的好处:
- 无视顺序:你不需要去记忆
skip_paused是在fq前面还是后面。 - 代码清晰:别人(或几个月后的你自己)阅读代码时,一眼就能看出
True或False代表的是什么意思,而不是看到一堆不明所以的布尔值。 - 安全健壮:即使未来官方真的在中间插入了新的参数,你的代码依然能够安全运行。
总结来说,虽然 API 设计上的不一致确实存在,但通过 Python 优秀的关键字传参特性,我们可以完美规避这个问题,写出优雅且健壮的量化策略代码。