讓我們進一步討論一下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.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成為元語言。lines
params
目標是讓使用該平臺的任何人的生活更輕鬆