编写设置方法

时间:2015-07-15 21:17:50

标签: python list properties decorator member

在我写的一个类中,其中一个成员属性是一个列表:

@property
def address_list(self):
    return self._address_list

@address_list.setter
def address_list(self, addr_list):
    if type(addr_list) is not list:
        return
    self._address_list = addr_list

我希望能够编写一个属性,所以如果有人想在列表中附加某些东西,它会调用类似于另一个setter函数的东西,但是要添加到列表中:

Object.address_list.append(value)

会调用类似

的内容
@property.appender # I made this line up
def address_list.append(self, value):
    if value >= 0 and value <= 127:
        self._address_list.append(value)

所以我可以安全地将值附加到我的私人列表中。这样的事情可以在不必创建新类型的列表对象的情况下实现吗?

编辑:地址列表返回标准python list

1 个答案:

答案 0 :(得分:2)

您需要创建一个新的AddressList类来处理这个问题。

之类的东西
class Wrapper(object):
    """Wrapper class that provides proxy access to an instance of some
       internal instance."""
    __wraps__  = None
    __ignore__ = "class mro new init setattr getattr getattribute"
    def __init__(self, obj):
        if self.__wraps__ is None:
            raise TypeError("base class Wrapper may not be instantiated")
        elif isinstance(obj, self.__wraps__):
            self._obj = obj
        else:
            raise ValueError("wrapped object must be of %s" % self.__wraps__)
    # provide proxy access to regular attributes of wrapped object
    def __getattr__(self, name):
        return getattr(self._obj, name)

    # create proxies for wrapped object's double-underscore attributes
    class __metaclass__(type):
        def __init__(cls, name, bases, dct):
            def make_proxy(name):
                def proxy(self, *args):
                    return getattr(self._obj, name)
                return proxy
            type.__init__(cls, name, bases, dct)
            if cls.__wraps__:
                ignore = set("__%s__" % n for n in cls.__ignore__.split())
                for name in dir(cls.__wraps__):
                    if name.startswith("__"):
                        if name not in ignore and name not in dct:
                            setattr(cls, name, property(make_proxy(name)))




class AddressList(Wrapper):
    __wraps__=list
    def append(self,x):
        if 0 <= x <= 127:
            self._obj.append(x)
        else:
            raise ValueError("Cannot append %r"%x)


class MyContainer:
    def __init__(self):
        self.address_list = AddressList([])


x = MyContainer()
x.address_list.append(1)
x.address_list.append(7)
x.address_list.append(-1)

print x.address_list

*请注意,此答案大量借鉴https://stackoverflow.com/a/9059858/541038 *