From e50172e923833856baead61f227e44531dd33e5d Mon Sep 17 00:00:00 2001 From: YuWuKunCheng Date: Fri, 29 May 2026 20:19:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20=E4=B8=AD=E6=9E=A2?= =?UTF-8?q?=E4=B8=80=E8=87=B4=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- chanlun-py/src/kline_py.rs | 6 +++--- chanlun-py/src/structure_py.rs | 36 +++++++++++++------------------- chanlun-py/src/types_py.rs | 35 +++++++++++++++++++++++++++++++ chanlun/src/algorithm/hub.rs | 2 +- chanlun/src/algorithm/segment.rs | 10 +++------ 5 files changed, 57 insertions(+), 32 deletions(-) diff --git a/chanlun-py/src/kline_py.rs b/chanlun-py/src/kline_py.rs index 752eab8..7ef4734 100644 --- a/chanlun-py/src/kline_py.rs +++ b/chanlun-py/src/kline_py.rs @@ -450,12 +450,12 @@ impl 缠论K线Py { } #[getter] - fn 分型(&self) -> Option { + fn 分型(&self, py: Python<'_>) -> Option> { self.inner .分型 .read() .unwrap() - .map(|f| crate::types_py::分型结构Py { inner: f }) + .map(|f| crate::types_py::获取分型结构单例(py, f)) } #[getter] @@ -506,7 +506,7 @@ impl 缠论K线Py { dict.set_item("与RSI匹配", self.与RSI匹配())?; dict.set_item("与KDJ匹配", self.与KDJ匹配())?; - if let Some(v) = self.分型() { + if let Some(v) = self.分型(py) { dict.set_item("分型", v)?; } Ok(dict.into()) diff --git a/chanlun-py/src/structure_py.rs b/chanlun-py/src/structure_py.rs index e7895d7..1680af6 100644 --- a/chanlun-py/src/structure_py.rs +++ b/chanlun-py/src/structure_py.rs @@ -184,22 +184,18 @@ impl 分型Py { } #[getter] - fn 结构(&self) -> 分型结构Py { - if chanlun::structure::fractal_obj::分型模式.load(Ordering::Relaxed) { - 分型结构Py { - inner: self.inner.结构, - } + fn 结构(&self, py: Python<'_>) -> Py<分型结构Py> { + let inner = if chanlun::structure::fractal_obj::分型模式.load(Ordering::Relaxed) { + self.inner.结构 } else { - 分型结构Py { - inner: self - .inner - .中 - .分型 - .read() - .unwrap() - .unwrap_or(chanlun::types::分型结构::散), - } - } + self.inner + .中 + .分型 + .read() + .unwrap() + .unwrap_or(chanlun::types::分型结构::散) + }; + crate::types_py::获取分型结构单例(py, inner) } #[getter] @@ -263,7 +259,7 @@ impl 分型Py { #[getter] fn __dict__(&self, py: Python<'_>) -> PyResult> { let dict = PyDict::new(py); - dict.set_item("结构", self.结构())?; + dict.set_item("结构", self.结构(py))?; dict.set_item("时间戳", self.时间戳())?; dict.set_item("分型特征值", self.分型特征值())?; dict.set_item("强度", self.强度())?; @@ -1280,17 +1276,15 @@ impl 特征分型Py { } #[getter] - fn 结构(&self) -> 分型结构Py { - 分型结构Py { - inner: self.inner.结构, - } + fn 结构(&self, py: Python<'_>) -> Py<分型结构Py> { + crate::types_py::获取分型结构单例(py, self.inner.结构) } /// pandas 兼容 — 返回关键标量字段构成的字典 #[getter] fn __dict__(&self, py: Python<'_>) -> PyResult> { let dict = PyDict::new(py); - dict.set_item("结构", self.结构())?; + dict.set_item("结构", self.结构(py))?; Ok(dict.into()) } diff --git a/chanlun-py/src/types_py.rs b/chanlun-py/src/types_py.rs index f802402..6c58436 100644 --- a/chanlun-py/src/types_py.rs +++ b/chanlun-py/src/types_py.rs @@ -22,10 +22,45 @@ * SOFTWARE. */ +use std::collections::HashMap; +use std::sync::Mutex; + use pyo3::basic::CompareOp; use pyo3::prelude::*; use pyo3::types::{PyDict, PyType}; +// ========== 单例缓存 ========== + +static 分型结构_单例缓存: Mutex>>> = Mutex::new(None); + +pub fn 获取分型结构单例( + py: Python<'_>, + inner: chanlun::types::分型结构, +) -> Py<分型结构Py> { + let mut guard = 分型结构_单例缓存.lock().unwrap(); + if let Some(ref map) = *guard { + return map[&(inner as u8)].clone_ref(py); + } + + // 首次访问时从类属性加载单例 + let module = py.import("chanlun._chanlun").unwrap(); + let class = module.getattr("分型结构").unwrap(); + let mut map = HashMap::new(); + for (name, variant) in &[ + ("上", chanlun::types::分型结构::上), + ("下", chanlun::types::分型结构::下), + ("顶", chanlun::types::分型结构::顶), + ("底", chanlun::types::分型结构::底), + ("散", chanlun::types::分型结构::散), + ] { + let instance: Py<分型结构Py> = class.getattr(*name).unwrap().extract().unwrap(); + map.insert(*variant as u8, instance); + } + let result = map[&(inner as u8)].clone_ref(py); + *guard = Some(map); + result +} + // ========== 买卖点类型 ========== /// 买卖点类型 — 缠论的三类买卖点及扩展类型。 diff --git a/chanlun/src/algorithm/hub.rs b/chanlun/src/algorithm/hub.rs index 90c6c02..2c540f8 100644 --- a/chanlun/src/algorithm/hub.rs +++ b/chanlun/src/algorithm/hub.rs @@ -387,7 +387,7 @@ impl 中枢 { /// 向中枢序列尾部添加 pub fn 向中枢序列尾部添加( - 中枢序列: &mut Vec>, mut 待添加中枢: Arc<中枢> + 中枢序列: &mut Vec>, 待添加中枢: Arc<中枢> ) { if let Some(前一个) = 中枢序列.last() { 待添加中枢 diff --git a/chanlun/src/algorithm/segment.rs b/chanlun/src/algorithm/segment.rs index b4afe82..6540c1a 100644 --- a/chanlun/src/algorithm/segment.rs +++ b/chanlun/src/algorithm/segment.rs @@ -474,7 +474,7 @@ impl 线段 { /// 分割序列 — 将线段的基础序列分为前、后、第三买卖线、贯穿伤 pub fn 分割序列( 段: &虚线, - mut 所属中枢: Option<&mut 中枢>, + 所属中枢: Option<&中枢>, ) -> ( Vec>, Vec>, @@ -517,7 +517,7 @@ impl 线段 { let mut 状态 = None; - if let Some(ref mut 中枢) = 所属中枢 { + if let Some(ref 中枢) = 所属中枢 { *中枢.本级_第三买卖线.write().unwrap() = None; let 尾部 = if let Some(ref 后笔) = 后.last() { 后笔.武.read().unwrap().clone() @@ -548,8 +548,6 @@ impl 线段 { } else { break; } - } else { - break; } } } @@ -568,15 +566,13 @@ impl 线段 { } else { break; } - } else { - break; } } } if !第三买卖线.is_empty() { 第三买卖线.reverse(); - if let Some(ref mut 中枢) = 所属中枢 { + if let Some(ref 中枢) = 所属中枢 { *中枢.本级_第三买卖线.write().unwrap() = Some(Arc::clone(&第三买卖线[0])); } }