让我们更多地解决Python 的隐藏功能如何在backtrader中使用, 以及如何实现它以尝试达到主要目标:易用性

这些定义是什么?

例如一个指标:

import backtrader as bt

class MyIndicator(bt.Indicator):

    lines = ('myline',)
    params = (('period', 20),)

    ...

任何能够阅读 python 的人都会说:

  • lines是一个tuple,实际上包含一个项目,一个字符串
  • params也是一个tuple,包含另一个tuple有 2 个项目

但后来

扩展示例:

import backtrader as bt

class MyIndicator(bt.Indicator):

    lines = ('myline',)
    params = (('period', 20),)

    def __init__(self):

        self.lines.myline = (self.data.high - self.data.low) / self.p.period

任何人都应该很明显,在这里:

  • lines中的定义已转换为一个属性,该属性可以作为并包含定义中指定的属性self.linesmyline

  • params中的定义已经变成了一个属性,它可以通过(或)来访问,并包含定义中指定的属性self.pself.paramsperiod而且self.p.period似乎有一个值,因为它直接用于算术运算(显然该值是定义中的值20:)

答案:元组

bt.Indicator因此也MyIndicator有一个元类,这允许应用元编程概念。

在这种情况下,拦截“lines”和“params”的定义,使它们成为:

  • 实例的属性,即:reachable asself.lines和 self.params
  • 的属性
  • 包含atributes其中定义的(和定义的值)

部分秘密

对于那些不精通元类的人来说,或多或少是这样做的:

class MyMetaClass(type):

    def __new__(meta, name, bases, dct):
        ...

        lines = dct.pop('lines', ())
        params = dct.pop('params', ())

        # Some processing of lines and params ... takes place here

        ...

        dct['lines'] = MyLinesClass(info_from_lines)
        dct['params'] = MyParamsClass(info_from_params)

        ...

在这里,的创建已被截获, lines并且params已将其定义替换为基于从定义中提取的信息的类。

仅此一项是达不到的,因此实例的创建也被拦截。使用 Pyton 3.x 语法:

class MyClass(Parent, metaclass=MyMetaClass):

    def __new__(cls, *args, **kwargs):

        obj = super(MyClass, cls).__new__(cls, *args, **kwargs)
        obj.lines = cls.lines()
        obj.params = cls.params()

        return obj

在这里,在上面定义为 的实例MyLinesClass中,并MyParamsClass已放入 的实例中 MyClass

不,没有冲突:

  • 该类可以这么说:“系统范围”并包含其自己的属性 ,哪些是linesparams
  • 实例可以这么说:“系统本地”,每个实例包含的实例(每次不同)linesparams

例如,通常可以使用访问self.lines实例,但也可以使用MyClass.lines访问类。

后者使用户可以访问方法,这些方法不适合一般用途,但这是 Python,没有什么可以被禁止的,更不用说开源了

结论

元组在幕后工作以提供一种机制,通过处理诸如tuple定义 linesparams

目标是让使用该平台的任何人的生活更轻松

评论被关闭。