星盘对象
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_name | int | 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参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
star | str | 是 | — | 星耀标识(如 "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"]))输出
命宫 迁移 财帛 官禄
三方四正见紫微: Trueis_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_name | int | str | 是 | — | 定位方式同 palace |
stars | list[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。调用前先确认列表非空。
horoscope
用途 以本盘为起点计算目标日期的运限。
签名
def horoscope(
self,
target_date: str | None = None,
target_time_index: int | None = None,
) -> Horoscope参数
| 参数 | 类型 | 必填 | 默认 | 说明 |
|---|---|---|---|---|
target_date | str | None | 否 | None | 目标公历日期;不传取今天 |
target_time_index | int | 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_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 上有同名的一对方法,形状一致,见运限对象。