从getter/setter到属性的自动转换

Rug*_*rra 3 python properties metaprogramming automatic-properties

我有一个用C++编写的大型库,有人创建了一个以自动方式在python(2.6)中使用它的接口.现在我有很多带有getter和setter方法的类.真的:我讨厌他们.

我想使用属性重新实现具有更多pythonic接口的类.问题是每个班级都有数百个getter和setter,而且我有很多课程.如何自动创建属性?

举例来说,如果我有一类叫做MyClassGetX()SetX(x),GetY,SetY,等...方法,我怎么能自动创建一个派生类MyPythonicClass与属性X(可读,如果有getter和可写的,如果有二传手)等上?我想要一种机制让我选择跳过一些getter/setter夫妇,最好是手工完成工作.

Joh*_*ooy 7

这是使用类装饰器完成此操作的方法

def make_properties(c):
    from collections import defaultdict
    props=defaultdict(dict)
    for k,v in vars(c).items():
        if k.startswith("Get"):
            props[k[3:]]['getter']=v
        if k.startswith("Set"):
            props[k[3:]]['setter']=v
    for k,v in props.items():
        setattr(c,k,property(v.get('getter'),v.get('setter')))
    return c

@make_properties
class C(object):
    def GetX(self):
        print "GetX"
        return self._x

    def SetX(self, value):
        print "SetX"
        self._x = value

c=C()
c.X=5
c.X
Run Code Online (Sandbox Code Playgroud)

这是一个稍微复杂的版本,允许您指定要跳过的项目列表

def make_properties(skip=None):
    if skip is None:
        skip=[]
    def f(c):
        from collections import defaultdict
        props=defaultdict(dict)
        for k,v in vars(c).items():
            if k.startswith("Get"):
                props[k[3:]]['getter']=v
            if k.startswith("Set"):
                props[k[3:]]['setter']=v
        for k,v in props.items():
            if k in skip:
                continue
            setattr(c,k,property(v.get('getter'),v.get('setter')))
        return c
    return f

@make_properties(skip=['Y'])
class C(object):
    def GetX(self):
        print "GetX"
        return self._x

    def SetX(self, value):
        print "SetX"
        self._x = value

    def GetY(self):
        print "GetY"
        return self._y

    def SetY(self, value):
        print "SetY"
        self._y = value

c=C()
c.X=5
c.X
c.Y=5
c.Y
Run Code Online (Sandbox Code Playgroud)