星盘对象

Astrolabe 的字段、定位方法,以及三方四正与夹宫。

Astrolabe 是排盘的产物,也是一切查询的入口。它是 frozen=True 的 dataclass, 持有十二宫的全部数据,以及四柱、命主身主、五行局这些盘级信息。

chart = Astro().by_solar("2000-8-16", 2, "female")

本页示例统一用默认的 zh-CN 排盘,因此输出里的展示值都是中文。 换语言只改这些展示串,*_key 标识与所有判断方法的结果不变。

字段


palace

用途 按索引、宫名、身宫或来因宫取一宫。

斗数含义 十二宫是斗数的骨架。命宫定下后,其余十一宫按固定顺序逆时针排开。 「身宫」是十二宫之一同时被标记的那一宫,代表后天着力处; 「来因宫」是宫干与生年干相同的那一宫,代表事情的起因。

签名

def palace(self, index_or_name: int | PalaceName | str) -> Palace | None

参数

参数类型必填默认说明
index_or_nameint | str是—四种写法见下表
写法例子含义
索引chart.palace(0)宫位索引 0–11,0 为寅宫
宫名标识chart.palace("soulPalace")十二宫名标识之一,即 PalaceName 的值域
当前语言宫名chart.palace("命宫")与排盘语言一致的宫名文本
身宫chart.palace("bodyPalace")带身宫标记的那一宫
来因宫chart.palace("originalPalace")宫干与生年干相同的那一宫

返回值 Palace | None。索引越界、宫名拼错时返回 None; 宫名、身宫、来因宫三种写法只要拼对,在任何一张盘上都能定位到。

示例

soul = chart.palace("soulPalace")
print(soul.name, soul.heavenly_stem + soul.earthly_branch)

print("身宫落在", chart.palace("bodyPalace").name)
print("来因宫是", chart.palace("originalPalace").name)
print("寅宫是", chart.palace(0).name)

输出

命宫 壬午
身宫落在 官禄
来因宫是 夫妻
寅宫是 财帛

边界与陷阱


star / star_in_palace

用途 按标识找到一颗星,或同时取回它所在的宫。

签名

def star(self, star: str) -> Star | None
def star_in_palace(self, star: str) -> tuple[Star, Palace] | None

参数

参数类型必填默认说明
starstr是—星耀标识(如 "ziweiMaj"),或当前排盘语言下的星名(如 "紫微")

返回值 该星不在这张盘上时返回 None。 star_in_palace 返回 (星, 宫) 二元组,省去再调 star.palace()。

示例

ziwei = chart.star("ziweiMaj")

print(ziwei.name, "在", ziwei.palace().name)
print("对宫是", ziwei.opposite_palace().name)
print("亮度", ziwei.brightness, "四化", ziwei.mutagen)

star, palace = chart.star_in_palace("ziweiMaj")
print(star.key, palace.name_key)

输出

紫微 在 命宫
对宫是 迁移
亮度 庙 四化 None
ziweiMaj soulPalace

边界与陷阱

只在主星、辅星、杂耀三组里查找。长生十二神、博士十二神、岁前与将前十二神 是每宫一个的标记而非星耀列表,用 palace.changsheng12_key 一类字段直接取。


surrounded_palaces

用途 取目标宫的三方四正。

斗数含义 三方四正是斗数最常用的取象范围:本宫、对宫(本宫 +6)、 官禄位(本宫 +4)、财帛位(本宫 +8)。四个宫合起来看,而不只看本宫, 是因为对宫与三合宫的星耀同样作用于本宫的事。

签名

def surrounded_palaces(self, index_or_name: int | PalaceName | str) -> SurroundedPalaces | None

参数 同 palace,四种定位写法都支持。

返回值 SurroundedPalaces | None,含 target / opposite / wealth / career 四个 Palace。 定位不到(索引越界或宫名拼错)时返回 None。判断方法见三方四正。

示例

sp = chart.surrounded_palaces("soulPalace")

print(sp.target.name, sp.opposite.name, sp.wealth.name, sp.career.name)
print("三方四正见紫微:", sp.have(["ziweiMaj"]))

输出

命宫 迁移 财帛 官禄
三方四正见紫微: True

is_surrounded / is_surrounded_one_of / not_surrounded

用途 直接在星盘上判断某宫的三方四正里有没有指定星耀,省去先取三方四正的一步。

签名

def is_surrounded(self, index_or_name: int | PalaceName | str, stars: list[str]) -> bool
def is_surrounded_one_of(self, index_or_name: int | PalaceName | str, stars: list[str]) -> bool
def not_surrounded(self, index_or_name: int | PalaceName | str, stars: list[str]) -> bool

参数

参数类型必填默认说明
index_or_nameint | str是—定位方式同 palace
starslist[str]是—星耀标识列表

返回值

方法语义
is_surrounded列表中每一颗都在三方四正里
is_surrounded_one_of列表中至少一颗在三方四正里
not_surrounded列表中一颗都不在三方四正里

示例

print(chart.is_surrounded("soulPalace", ["ziweiMaj", "tianxiangMaj"]))
print(chart.is_surrounded_one_of("soulPalace", ["qishaMaj", "pojunMaj"]))
print(chart.not_surrounded("soulPalace", ["huoxingMin"]))

输出

True
False
True

命宫只坐紫微,天相在三方之一的财帛宫,因此第一行为真; 七杀与破军都不在这四宫内,第二行为假。

边界与陷阱

空列表的返回值

stars 传空列表时,is_surrounded 与 not_surrounded 返回 True (「所有元素都满足」与「没有元素不满足」对空集都成立), is_surrounded_one_of 返回 False。调用前先确认列表非空。


flanking_palaces

用途 取目标宫的夹宫:盘上紧邻它前后的两宫。

斗数含义 「羊陀夹忌」「日月夹命」这类说法看的就是夹宫。 夹宫与三方四正是两条不重叠的线索:三方四正问的是同一组能量彼此呼应, 夹宫问的是这一宫左右两侧的处境。

签名

def flanking_palaces(self, index_or_name: int | PalaceName | str) -> FlankingPalaces | None

参数 同 palace,四种定位写法都支持。

返回值 FlankingPalaces | None,两个 Palace 字段。定位不到时返回 None。

字段相对目标宫说明
previous-1前一宫
next+1后一宫

十二宫首尾相连,索引对 12 回绕:第 0 宫的前一宫是第 11 宫。 另有 astrolabe() 取回两宫所属的星盘。

五个判断方法与三方四正同名同义,只是作用范围换成这两宫:

方法语义
have(stars: list[str]) -> bool两宫合起来含列表中每一颗
not_have(stars: list[str]) -> bool两宫一颗都不含
have_one_of(stars: list[str]) -> bool两宫合起来至少含一颗
have_mutagen(mutagen: Mutagen) -> bool两宫中有任一宫带该生年四化
not_have_mutagen(mutagen: Mutagen) -> bool两宫都不带

星耀既可以写 MajorStar / MinorStar 这些枚举,也可以写当前语言的星名。

示例

f = chart.flanking_palaces("soulPalace")

print(f.previous.name, "/", f.next.name)
print(f.have(["tianjiMaj", "tuoluoMin"]))
print(f.have_one_of(["huoxingMin"]))

w = chart.flanking_palaces("wealthPalace")
print(w.previous.name, "/", w.next.name)
print(w.have_mutagen("sihuaLu"), w.have_mutagen("sihuaJi"))

输出

兄弟 / 父母
True
False
疾厄 / 子女
True True

命宫在午,夹它的是兄弟(巳)与父母(未)。天机坐兄弟、陀罗坐父母,分处两宫, have 仍然成立;火星坐夫妻,不在这两宫之内,因此 have_one_of 为 False。 财帛在寅,夹它的疾厄坐天同、子女坐太阳,这张盘生年干庚使太阳化禄、天同化忌, 于是禄与忌两问都为 True。

边界与陷阱


horoscope

用途 以本盘为起点计算目标日期的运限。

签名

def horoscope(
    self,
    target_date: str | None = None,
    target_time_index: int | None = None,
) -> Horoscope

参数

参数类型必填默认说明
target_datestr | None否None目标公历日期;不传取今天
target_time_indexint | None否None目标时辰索引;不传取此刻所属时辰

返回值 Horoscope——持有本盘的运限对象,六个层级的宫位查询不必再传星盘。 详见运限对象。

示例

h = chart.horoscope("2025-6-1", 0)

print("大限", h.decadal.heavenly_stem + h.decadal.earthly_branch)
print("流年", h.yearly.heavenly_stem + h.yearly.earthly_branch)

# 两个参数都可省略,取当下
now = chart.horoscope()

输出

大限 庚辰
流年 乙巳

to_text

用途 星盘的语义化文本:面向语言模型与人的完整描述,str(chart) 等价。

签名

def to_text(
    self,
    *,
    knowledge: bool | KnowledgePack | None = None,
    config: PatternConfig | None = None,
) -> str

参数

参数类型必填默认说明
knowledgebool | KnowledgePack | None否None释义材料:True 取排盘语言的内嵌默认包,KnowledgePack 用该包(自定义或合并后的包);给出时释义内联在事实之后——格局列表后跟格局释义(含成立条件),每宫事实后跟该宫星耀释义(同宫主星组合在前),文末附 ## 四化释义
configPatternConfig | None否None格局判定口径,与 patterns(config) 同一入参;同时作用于文本的格局节与格局释义。None 取默认口径

返回值 str——按排盘语言输出的 Markdown 子集:# 命盘 … 标题、## 基本信息、 ## 十二宫总览(表)、## 格局、## 十二宫(从命宫起每宫一段 ### )。 完整格式见语义化文本,释义的插入位置见 带释义的文本。

示例

print(chart.to_text().splitlines()[0])

text = chart.to_text(knowledge=True)
print(len(chart.to_text()), len(text))
print(" ".join(l for l in text.splitlines() if l.startswith("## ")))

输出

# 命盘 2000-8-16 寅时 女
3389 20767
## 基本信息 ## 十二宫总览 ## 格局 ## 十二宫 ## 四化释义

边界与陷阱

knowledge=True 而排盘语言没有内嵌包(目前只有 zh-CN 有)抛 IztroError(invalid_argument), 不会静默退回无释义;英文盘显式传一份 KnowledgePack 即可。

单宫与三方四正的文本见 palace(...).to_text() 与 surrounded_palaces(...).to_text(), 格局文本见 patterns_to_text(格局判定)。


to_dict / to_json

用途 把星盘导出成与 JS iztro 字段契约一致的 JSON。

签名

def to_dict(self) -> dict[str, Any]
def to_json(self, **kwargs: Any) -> str

参数

参数类型必填默认说明
kwargs—否—仅 to_json:透传给 json.dumps,如 indent=2、sort_keys=True

to_json 默认 ensure_ascii=False,中文直接落在输出里而不是 \uXXXX。

返回值 to_dict 返回底层 DTO 的深拷贝——camelCase 键、值按排盘语言翻译, 另带 *Key 语言无关标识与排盘上下文。改它不会影响星盘。 to_json 返回同一份数据的 JSON 字符串,内容与 iztro 的 JSON.stringify(astrolabe) 逐键逐值对应。

示例

d = chart.to_dict()
print(d["solarDate"], d["palaces"][4]["nameKey"])
print(d["config"]["yearDivide"], d["genderKey"], d["timeIndex"])

import json
print(json.dumps({k: d[k] for k in ("gender", "solarDate", "lunarDate")},
                 ensure_ascii=False))
print(len(chart.to_json()) > 10000, chart.to_json()[:1])

输出

2000-8-16 soulPalace
normal female 2
{"gender": "女", "solarDate": "2000-8-16", "lunarDate": "二〇〇〇年七月十七"}
True {

键的顺序是字典序

底层 DTO 经原生扩展转成 Python dict 时按键名排序, 因此 to_dict() / to_json() 的顶层键是 body、bodyKey、chineseDate…… 这个次序, 不是 iztro 声明字段的次序。键名与取值逐个对应,只是排列不同; 要固定次序请自己按需要挑键输出。

边界与陷阱

不要用 dataclasses.asdict 导出

Astrolabe、Palace、Star 都是 dataclass,但宫位与星耀各自持有一个指回本盘的 引用(_astrolabe / _palace)。dataclasses.asdict(chart) 会顺着这条回指 无限递归,最终 RecursionError。

导出一律走 to_dict() / to_json()——它们直接拿底层 DTO,既不递归也不丢字段。

自定义表不在导出里

config 只回显六个开关。排盘时传的自定义四化 / 亮度表是输入而非结果, 不进 DTO——这一点与 JS iztro 的字段契约一致。要记录用了哪张表, 请在自己的调用侧保存 ChartConfig。

Horoscope 上有同名的一对方法,形状一致,见运限对象。

本页目录