将多个 xarray 访问器组合成一个

combine multiple xarray accessors into single one

假设我注册了多个 xarray 访问器:

import xarray as xr

@xr.register_dataarray_accessor("a")
class A:
    def __init__(self, xarray_obj):
        self._obj = xarray_obj

    def print(self):
        return "A"

@xr.register_dataarray_accessor("b")
class B:
    def __init__(self, xarray_obj):
        self._obj = xarray_obj

    def print(self):
        return "b"
        
@xr.register_dataarray_accessor("c")
class C:
    def __init__(self, xarray_obj):
        self._obj = xarray_obj

    def print(self):
        return "c"

xr.DataArray().a.print()
# a

xr.DataArray().b.print()
# b

xr.DataArray().c.print()
# c

有没有一种好方法可以将它们“移动”到充当某种父访问器的单个访问器中?

假设这个父项被称为 z,我想要的结果将如下所示:

xr.DataArray().z.a.print()
# a

xr.DataArray().z.b.print()
# b

xr.DataArray().z.c.print()
# c

编辑:

这只是一个玩具示例,当然所有嵌套对象都需要能够访问 Z 获取的 self._obj

您注册为访问器的对象可以做任何您想做的事情,包括拥有自己的方法、属性等。一些完整的包可用作 xarray 访问器 - 我正在考虑 rioxarray,其中da.rio 具有大量功能。

因此,对于您的情况,您可以简单地执行以下操作:

class Printable:
    def __init__(self, obj):
        self._obj = obj

    def print_me(self):
        print(
          type(self).__name__.lower()
          + '\n'
           + str(self._obj)
        )

class A(Printable):
    pass

class B(Printable):
    pass

class C(Printable):
    pass

@xr.register_dataarray_accessor("z")
class Z:
    def __init__(self, xarray_obj):
        self._obj = xarray_obj

        self.a = A(xarray_obj)
        self.b = B(xarray_obj)
        self.c = C(xarray_obj)

这具有您正在寻找的行为:

In [6]: xr.DataArray().z.a.print_me()
a
<xarray.DataArray ()>
array(nan)

In [7]: xr.DataArray().z.b.print_me()
b
<xarray.DataArray ()>
array(nan)

In [8]: xr.DataArray().z.c.print_me()
c
<xarray.DataArray ()>
array(nan)

必须指出,我强烈建议不要使用保留关键字作为方法名称。我知道这是一个虚拟示例,但为了安全起见,我已将其更改为 print_me :)