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

时间:2016-04-12 18:08:10

标签: python properties factory descriptor python.net

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

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

CustomList

总的来说,我必须处理大约50处房产。对于几组属性,我想添加自己的错误检查,键入转换等。 我正在寻找的是一种定义属性的Pythonic方法,例如:通过工厂或使用描述符。谢谢你的帮助!

编辑:我希望能够在python shell中使用tab完成,即表面。 {hit tab}应该提出surface.width和surface.height。使用Greg概述的 getattr 方法似乎无法做到这一点。

2 个答案:

答案 0 :(得分:5)

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

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)

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

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.')

答案 1 :(得分:1)

如果要避免所有手动编码,可以使用getattr和setattr。这个答案适用于python2 btw。

class MySurface(object):
    def __init__(self):
        self.props = {"width": 0, "length": 0, ...}

    def __setattr__(self, attr, val):
        if attr in self.props:
            self.props[attr] = val
        else:
            super(MySurface, self).__setattr__(attr, val)

    def __getattr__(self, attr):
        if attr in self.props:
           return self.props[attr]
        else:
           return self.__getattribute__(attr)