用于包装外部库的Python属性工厂或描述符类

Ola*_*laf 5 python factory properties descriptor python.net

我正在为通过Pythonnet访问的C#API编写Python包装器类。当我想用自己的方法扩展API时,我决定使用此处概述的组合方法包装它:

C#API大量使用了我想在我的Python代码中模仿的属性。下面的最小示例显示了我当前使用C#Surface类的示例的方法,该类具有两个属性width和height:

class MySurface:
    def __init__(api_surface):
        self.api_surface = api_surface

    @property
    def width(self):
        return self.api_surface.width

    @width.setter
    def width(self, value):
        self.api_surface.width = value

    @property
    def height(self):
        return self.api_surface.height

    @height.setter
    def height(self, value):
        self.api_surface.height = value
Run Code Online (Sandbox Code Playgroud)

总共我必须处理大约50个属性。对于几组属性,我想添加自己的错误检查,类型转换等。我正在寻找一种Python方式定义属性,例如通过工厂或使用描述符。谢谢你的帮助!

编辑:我希望能够在python shell(即曲面)中使用制表符补全。{hit标签}应该建议surface.width和surface.height。用Greg概述的getattr方法似乎不可能做到这一点。

Ola*_*laf 6

我可以使用以下属性工厂解决问题:

def surface_property(api_property_name, docstring=None):
    def getter(self):
        return self.api_surface.__getattribute__(api_property_name)

    def setter(self, value):
        self.api_surface.__setattr__(api_property_name, value)

    return property(getter, setter, doc=docstring)
Run Code Online (Sandbox Code Playgroud)

使用此函数,类定义可简化为:

class MySurface:
    def __init__(api_surface):
        self.api_surface = api_surface

    width = surface_property('Width','Get and set the width.')
    height = surface_property('height', 'Get and set the height.')
Run Code Online (Sandbox Code Playgroud)