初始归档:健康管理资料库(大医网/药膳/体质监测/中医理论等12个资料集,7712个文件)

This commit is contained in:
512song committed 2026-09-23 21:59:25 +08:00
commit 80ae3811cf
7712 files changed
+4628547

No files matched your search

@@ -0,0 +1,215 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
《中医入门》理论依据查询接口(应用调用层)
用法:
from theory_api import TCMTheory
t = TCMTheory()
t.herb("黄芪") # 药材理论依据: 效能分类/功效药组/治法/用药安全
t.formula("大承气汤") # 方剂理论依据: 主方定位/主治/七方归属/组成药组
t.safety_check(["甘草","大戟"]) # 配伍安全核查: 十八反/十九畏/妊娠禁忌
t.method("补中益气") # 治法查询(名称模糊)
t.constitution("气虚") # 体质调理依据(按气虚/阳虚/阴虚等关键词聚合)
依据均含 行号(02_加工数据/中医入门.md) 可人工溯源。
"""
import json, os, re
LIB = os.path.join(os.path.dirname(__file__), "../02_加工数据/理论依据库.json")
BOOK = os.path.join(os.path.dirname(__file__), "../02_加工数据/中医入门.md")
# 书侧简写 → 正名(与 reverse_tag 脚本一致的归一)
BOOK_ALIAS = {"山萸":"山茱萸","萸肉":"山茱萸","麻仁":"火麻仁","云苓":"茯苓","赤苓":"茯苓",
"云茯神":"茯神","银花":"金银花","杭菊花":"菊花","花粉":"天花粉","寸冬":"麦冬",
"生地":"生地黄","熟地":"熟地黄","鲜生地":"生地黄","肉果":"肉豆蔻","淡苁蓉":"肉苁蓉",
"吴萸":"吴茱萸","川连":"黄连","潼沙苑":"沙苑子","仙灵脾":"淫羊藿","旱莲草":"墨旱莲",
"丹皮":"牡丹皮","茅根":"白茅根","象贝母":"浙贝母","川贝":"川贝母","白蒺藜":"刺蒺藜",
"菟丝饼":"菟丝子","桑椹子":"桑椹","使君肉":"使君子","山查炭":"山楂","焦麦芽":"麦芽",
"炒莱菔子":"莱菔子","驴皮胶":"阿胶","龟版":"龟板","菟蓉":"肉苁蓉","金铃子":"川楝子",
"延胡":"延胡索","参三七":"三七","全当归":"当归","当归身":"当归","冬虫草":"冬虫夏草",
"蝉衣":"蝉蜕","瓜蒌仁":"瓜蒌子","左牡蛎":"牡蛎","生石决":"石决明","羚羊尖":"羚羊角",
"炙全蝎":"全蝎","炒谷芽":"谷芽","春砂仁":"砂仁","白蔻仁":"豆蔻","御米壳":"罂粟壳",
"煨葛根":"葛根","炙升麻":"升麻","软柴胡":"柴胡","煨草果":"草果","炒苡仁":"薏苡仁",
"饭赤豆":"赤小豆","白藓皮":"白鲜皮","炙兜铃":"马兜铃","黑山栀":"栀子","炒竹茹":"竹茹",
"炙桑皮":"桑白皮","炒牛蒡":"牛蒡子","苦桔梗":"桔梗","石草":"石韦","淡菓蓉":"肉苁蓉",
"复盆子":"覆盆子","菖蒲":"石菖蒲","萹蓄草":"萹蓄","海金砂":"海金沙",}
PREP_PREFIX = ["生晒","炙","煨","煅","焦","炒","制","飞","清","法","霜","酒","醋","盐",
"蜜","麸","鲜","干","姜","蒸","煮"] # 只剥炮制前缀;产地品质限定词不剥(土人参陷阱)
def _norm(name: str):
c = name.strip()
for p in PREP_PREFIX:
if c.startswith(p) and len(c) > len(p) + 1:
c = c[len(p):]; break
return BOOK_ALIAS.get(c, c)
class TCMTheory:
def __init__(self):
self.lib = json.load(open(LIB, encoding="utf-8"))
self.book_lines = open(BOOK, encoding="utf-8").read().splitlines()
# 索引: 药名(正名+别名+炮制品) → 锚点
self.herb_index = {}
for cat, info in self.lib["效能分类"].items():
for h in info["代表药"]:
self.herb_index.setdefault(_norm(h), []).append({"通道": "效能分类", "值": cat, "行号": info["行号"]})
for g in self.lib["功效药组"]["条目"]:
for h in g["药"]:
self.herb_index.setdefault(_norm(h), []).append({"通道": "功效药组", "值": g["组"], "行号": g["行号"]})
for num, z in self.lib["治法72"]["条目"].items():
for h in z["药如"]:
self.herb_index.setdefault(_norm(h), []).append({"通道": "治法", "值": f"治法{num}.{z['名称']}", "行号": z["行号"]})
self.safety_index = {}
for grp in self.lib["用药安全"]["十八反"]["相反组"]:
for a in grp["组"]:
self.safety_index.setdefault(a, []).append(("十八反", f'与{"、".join(grp["反"])}相反', "书列"))
for a in grp.get("组_通行扩展", []):
self.safety_index.setdefault(a, []).append(("十八反", f'与{"、".join(grp["反"])}相反', "通行扩展"))
for h in grp["反"]:
who = "、".join(grp["组"] + grp.get("组_通行扩展", []))
self.safety_index.setdefault(h, []).append(("十八反", f"反{who}", "书列"))
for h in grp.get("反_通行扩展", []):
who = "、".join(grp["组"] + grp.get("组_通行扩展", []))
self.safety_index.setdefault(h, []).append(("十八反", f"反{who}", "通行扩展"))
for a, b in self.lib["用药安全"]["十九畏"]["畏对"]:
self.safety_index.setdefault(a, []).append(("十九畏", f"畏{b}", "书列"))
self.safety_index.setdefault(b, []).append(("十九畏", f"为{a}所畏", "书列"))
for h in self.lib["用药安全"]["妊娠禁忌"]["药"]:
self.safety_index.setdefault(h, []).append(("妊娠禁忌", "妊娠禁忌药", "书列"))
def _quote(self, line_no, width=60):
if 1 <= line_no <= len(self.book_lines):
return self.book_lines[line_no - 1][:width]
return None
# ---------- 药材理论依据 ----------
def herb(self, name: str):
n = _norm(name)
hits = self.herb_index.get(n, []) or self.herb_index.get(name.strip(), [])
if not hits:
return {"药材": name, "结果": "《中医入门》理论药组未收录(该书为入门纲要,未收不等于无理论依据)"}
out = {"药材": name, "正名": n, "依据": []}
seen = set()
for h in hits:
key = (h["通道"], h["值"])
if key in seen: continue
seen.add(key)
out["依据"].append({**h, "原文": self._quote(h["行号"])})
out["用药安全"] = self._safety_of(n)
return out
# ---------- 方剂理论依据 ----------
def formula(self, name: str):
s = self.lib["示例方40"].get(name.strip())
if not s:
# 组成含书侧示例方药的模糊建议
return {"方剂": name, "结果": "非书侧40示例方;可按组成逐味调用 herb() 获取理论依据",
"剂型理论": self._jixing_hint(name)}
out = {"方剂": name, "主方定位": s["主方定位"], "主治": s["主治"],
"组成_书": s["组成_书"], "行号": s["行号"], "原文": self._quote(s["行号"], 120),
"七方归属": [q for q, v in self.lib["七方"].items() if name in v["书内举例"]] or None,
"组成理论": []}
safety_all = []
for h in s["组成_书"]:
hb = self.herb(h)
ch = [f'{d["通道"]}:{d["值"]}' for d in hb.get("依据", [])][:3]
out["组成理论"].append({"药": h, "依据": ch})
if hb.get("用药安全"): safety_all.append({h: hb["用药安全"]})
if safety_all: out["组成用药安全"] = safety_all
return out
# ---------- 配伍安全核查 ----------
def safety_check(self, herbs):
herbs = [h.strip() for h in herbs if h.strip()]
conflicts, warnings = [], []
normalized = {h: _norm(h) for h in herbs}
names = list(normalized.items())
# 十八反: 组内对立(含通行扩展,结果标注来源)
for grp in self.lib["用药安全"]["十八反"]["相反组"]:
side_a = {(h, n) for h, n in names
if n in grp["组"] or n in grp.get("组_通行扩展", [])}
side_b = {(h, n) for h, n in names
if n in grp["反"] or n in grp.get("反_通行扩展", [])}
if side_a and side_b:
src = "书列"
a_ext = any(n in grp.get("组_通行扩展", []) for _, n in side_a)
b_ext = any(n in grp.get("反_通行扩展", []) for _, n in side_b)
if a_ext or b_ext: src = "通行扩展"
conflicts.append({"类型": "十八反", "来源": src,
"组": sorted(h for h, _ in side_a), "反": sorted(h for h, _ in side_b),
"行号": self.lib["用药安全"]["十八反"]["行号"]})
# 十九畏: 组内畏对
pairset = {frozenset(p) for p in self.lib["用药安全"]["十九畏"]["畏对"]}
for i in range(len(names)):
for j in range(i + 1, len(names)):
if frozenset([names[i][1], names[j][1]]) in pairset:
warnings.append({"类型": "十九畏", "对": [names[i][0], names[j][0]],
"行号": self.lib["用药安全"]["十九畏"]["行号"]})
# 妊娠禁忌
preg = [h for h, n in names
if n in self.lib["用药安全"]["妊娠禁忌"]["药"] or h in self.lib["用药安全"]["妊娠禁忌"]["药"]]
return {"核查药味": herbs, "十八反冲突": conflicts or None,
"十九畏警式": warnings or None,
"妊娠禁忌药": preg or None,
"结论": "存在配伍禁忌,须调整" if conflicts else
("有相畏提示,慎用并权衡" if warnings else
("含妊娠禁忌药,孕妇须避" if preg else "书侧十八反/十九畏/妊娠禁忌未命中"))}
# ---------- 治法 ----------
def method(self, keyword: str):
out = []
for num, z in self.lib["治法72"]["条目"].items():
hay = z["名称"] + (z["适应症"] or "")
if keyword in z["名称"] or keyword in hay or z["名称"][:2] in keyword:
out.append({"治法": f"{num}.{z['名称']}", "适应症": z["适应症"],
"药如": z["药如"], "行号": z["行号"],
"原文": self._quote(z["行号"])})
for bn, bv in self.lib["八法"].items():
if keyword in bn or keyword in bv["定义原文"] or bn[0] in keyword:
out.append({"八法": bn, "定义": bv["定义原文"], "行号": bv["行号"]})
return {"关键词": keyword, "命中": out or None}
# ---------- 体质调理依据 ----------
CONSTITUTION_SYNONYMS = {
"气虚": ["补气", "中气"], "血虚": ["补血", "养血"], "阴虚": ["补阴", "滋阴", "养阴"],
"阳虚": ["补阳", "助阳", "温阳", "扶阳"], "痰湿": ["化湿", "化痰", "淡渗"],
"湿热": ["清湿热", "化湿", "利湿"], "血瘀": ["活血", "破瘀"], "气滞": ["行气", "破气", "疏肝"],
"寒": ["温中", "祛寒", "散寒", "扶阳"], "热": ["清热", "泻火", "凉血"], "食积": ["消食", "消导"]}
def constitution(self, keyword: str):
"""按 气虚/血虚/阴虚/阳虚/痰湿/湿热/血瘀/气滞/寒/热/食积 等关键词聚合理论依据"""
syns = self.CONSTITUTION_SYNONYMS.get(keyword, [keyword])
res = {"关键词": keyword, "同义词展开": syns, "补益药组": [], "治法": [], "八法": []}
for g in self.lib["功效药组"]["条目"]:
if any(s in g["组"] for s in syns):
res["补益药组"].append({"组": g["组"], "药": g["药"], "行号": g["行号"]})
for num, z in self.lib["治法72"]["条目"].items():
hay = z["名称"] + (z["适应症"] or "")
if any(s in hay for s in syns):
res["治法"].append({"治法": f"{num}.{z['名称']}", "药如": z["药如"], "行号": z["行号"]})
for bn, bv in self.lib["八法"].items():
if any(s in bv["定义原文"] for s in syns):
res["八法"].append({"八法": bn, "行号": bv["行号"]})
res["提示"] = "示例方与药组的完整组成请调用 formula()/herb() 逐层获取" if (res["补益药组"] or res["治法"]) else None
return res
# ---------- 内部 ----------
def _safety_of(self, n):
recs = self.safety_index.get(n, [])
out = {}
for typ, desc, src in recs:
out.setdefault(typ, []).append(f"{desc}[{src}]" if src != "书列" else desc)
return out or None
def _jixing_hint(self, name):
m = re.search(r'(丸|散|膏|丹|酒|汤|饮)', name)
if not m: return None
jx = m.group(1)
return {"剂型": jx, "说明": "丸散膏丹等剂型各具性质效用(方剂之部·剂型)"}
if __name__ == "__main__":
t = TCMTheory()
print("== herb 黄芪 =="); print(json.dumps(t.herb("黄芪"), ensure_ascii=False, indent=1)[:600])
print("\n== formula 大承气汤 =="); print(json.dumps(t.formula("大承气汤"), ensure_ascii=False, indent=1)[:700])
print("\n== safety 甘草+大戟 =="); print(json.dumps(t.safety_check(["甘草", "大戟", "茯苓"]), ensure_ascii=False, indent=1))
print("\n== method 补中 =="); print(json.dumps(t.method("补中"), ensure_ascii=False, indent=1)[:400])
print("\n== constitution 气虚 =="); print(json.dumps(t.constitution("气虚"), ensure_ascii=False, indent=1)[:500])