讓我們進一步討論一下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
目標是讓使用該平臺的任何人的生活更輕鬆