让我们进一步讨论一下Python的隐藏功能如何在 backtrader 中使用,以及如何实现它以尝试实现主要目标:易用性
这些定义是什么?
例如指针:
import backtrader as bt
class MyIndicator(bt.Indicator):
    lines = ('myline',)
    params = (('period', 20),)
    ...
任何能够阅读python的人都会说:
-  
lines是一个tuple,实际上包含单个项目,一个字符串 -  
params也是一个tuple,包含另一个有tuple2 个项目 
但后来
扩展示例:
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.lines并依次包含定义中指定的属性myline来访问 
和
-  
类中的 定义
params已转换为属性,可以作为self.p(或self.params) 访问,并依次包含定义中指定的属性period并且
self.p.period似乎有一个值,因为它直接用于算术运算(显然该值是定义中的值:20) 
答案:元类
bt.Indicator 因此也有 MyIndicator 一个元类,这允许应用元编程概念。
在这种情况下,拦截「」的定义lines」和「参数」,使它们成为:
-  
实例的属性,即:可访问为
self.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中。
不,没有冲突:
-  
该类可以说:「系统范围」 并包含其自己的属性
lines,params哪些是类 -  
该实例可以说:「系统本地」,并且每个实例都包含和的
lines实例(每次都不同)params 
通常,例如,一个将用于self.lines 访问实例,但也可以使用 MyClass.lines 访问类。
后者使用户可以访问方法,这些方法不是用于一般用途的,但这是Python,没有什么可以被禁止的,更不用说 Open Source了。
结论
元类正在幕后工作,以提供一种机制,通过处理诸如和的定义之类的tuple东西,使almos成为元语言。linesparams
目标是让使用该平台的任何人的生活更轻松