扩展星盘

用插件给 Astrolabe 类挂自定义分析方法。

斗数的分析规则千人千面,库不可能穷举。x-iztro 让你把自己的规则 以方法的形式挂到星盘类上——调用语法与内置方法一致,所有星盘实例都能用。

配方

一个插件就是一个函数,接受 Astrolabe 类并往上挂方法。

写一个接受 type[Astrolabe] 的函数
在函数体里定义方法,赋值到类上
load_plugin 加载
from x_iztro import Astro, Astrolabe, PalaceName
from x_iztro.plugin import load_plugin


def my_analysis(cls: type[Astrolabe]) -> None:
    """给星盘补两个自定义分析方法。"""

    def major_star(self) -> str:
        """命宫主星名(空宫借对宫),多颗以逗号分隔"""
        soul = self.palace(PalaceName.SOUL)
        source = soul.opposite_palace() if soul.is_empty() else soul
        return ",".join(s.name for s in source.major_stars)

    def five_elements_value(self) -> int:
        """五行局的局数"""
        return int(self.five_elements_class_key[-3])

    cls.major_star = major_star
    cls.five_elements_value = five_elements_value


load_plugin(my_analysis)

用法

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

print(chart.major_star())

# 扩展方法随排盘语言输出
en = Astro().by_solar("2000-8-16", 2, "female", language="en-US")
print(en.major_star())

输出

紫微
emperor

load_plugin / load_plugins

签名

def load_plugin(plugin: Plugin) -> None
def load_plugins(plugins: Iterable[Plugin]) -> None

Plugin 的类型是 Callable[[type[Astrolabe]], None]

参数

参数类型必填默认说明
pluginPlugin接受 Astrolabe 类的函数
pluginsIterable[Plugin]按顺序加载的多个插件

返回值 None。方法直接挂到类上。

边界与陷阱


为什么能挂上去

Astrolabeslots=True 的 frozen dataclass,实例上挂不了属性:

try:
    chart.foo = 1
except Exception as e:
    print(type(e).__name__, e)

输出

FrozenInstanceError cannot assign to field 'foo'

上挂方法不受影响。这正是插件需要的粒度: 插件改的是「所有星盘都有这个方法」,不是「这一张盘多了个字段」。


扩展别的类型

同一套写法适用于宫位与星耀,直接给对应的类挂方法即可:

from x_iztro.models import Palace


def palace_analysis(cls: type[Palace]) -> None:
    def is_afflicted(self) -> bool:
        """本宫是否「煞忌交冲」:坐煞星且带化忌"""
        sha = ["qingyangMin", "tuoluoMin", "huoxingMin",
               "lingxingMin", "dikongMin", "dijieMin"]
        return self.has_one_of(sha) and self.has_mutagen("sihuaJi")

    cls.is_afflicted = is_afflicted


palace_analysis(Palace)
for p in chart.palaces:
    if p.is_afflicted():
        print(p.name, "煞忌交冲")

输出

疾厄 煞忌交冲

load_plugin 只接受作用于 Astrolabe 的插件。要挂到别的类上, 像上例那样直接调用函数即可——插件机制本身没有魔法。


组织建议

本页目录