Hi Chris,
  in attachment is proposal for decorator version of propcan as we talked 
before.
>From the line 48 is decorator implementation.
    pproperty is compatible with python 2.4.3 which is in rhel 5.
When later version of the python is used it is be possible use build-in 
property.
Please take a look a let me know what you mean about this implementation.

only problem which I could see is the need to define wildcard slots _x instead 
of x.
Example:
   class D(PropCan, CopySlots):
       __slots__ = ['_x', 'y']

       @pproperty
       def x(self):
           """ aaaa """
           print "Get"
           return self._x

       @x.setter
       def x(self, value):
           print "Set"
           self._x = value

       @x.deleter
       def x(self):
           del self._x

regards,
   Jiří Župka
import copy
import cPickle


class Propcan(object):
    __slots__ = ('__doc__', "fset", "fget", "fdel")

    def __init__(self, fn):
        super(Propcan, self).__setattr__("fget", fn)

    def setter(self, fn):
        super(Propcan, self).__setattr__("fset", fn)

    def deleter(self, fn):
        super(Propcan, self).__setattr__("fdel", fn)

    def __get__(self, obj, value):
        return self.fget(obj)

    def __set__(self, obj, value):
        self.fset(obj, value)

    def __del__(self, obj):
        self.fdel(obj)


class C(object):
    __slots__ = ['_x', 'y']

    def __init__(self):
        self._x = None

    @Propcan
    def x(self):
        print "Get"
        return self._x

    @x.setter
    def set_x(self, value):
        print "Set"
        self._x = value

    @x.deleter
    def del_x(self):
        del self._x


class pproperty(property):
    __slots__ = ["__doc__"]

    def __init__(self, fget, fset=None, fdel=None, doc=None):
        super(pproperty, self).__init__(fget,
                                        fset,
                                        fdel,
                                        doc)
        if not hasattr(self, '__doc__'):
            if doc:
                self.__doc__ = doc
            else:
                self.__doc__ = fget.func_doc

    def getter(self, fget):
        return pproperty(fget, self.fset, self.fdel, self.__doc__)

    def setter(self, fset):
        return pproperty(self.fget, fset, self.fdel, self.__doc__)

    def deleter(self, fdel):
        return pproperty(self.fget, self.fset, fdel, self.__doc__)


if not hasattr(property, "setter"):
    property = pproperty


class classproperty(property):
    def __get__(self, obj, type_):
        data = self.fget.__get__(None, type_)()
        return data

    def __set__(self, obj, value):
        cls = type(obj)
        return self.fset.__get__(None, cls)(value)


class CopySlots(object):
    def copy(self):
        return copy.copy(self)


class PropCan(object):

    """
    Special value handling on retrieval of None values
    """
    ___all_slots__ = []

    @classproperty
    @classmethod
    def __all_slots__(cls):
        if not cls.___all_slots__:
            all_slots = []
            for cls_slots in [getattr(_cls, '__slots__', [])
                              for _cls in cls.__mro__]:
                all_slots += cls_slots
            cls.___all_slots__ = all_slots
        return cls.___all_slots__

    def __len__(self):
        return len(self.__all_slots__)

    def __contains__(self, key):
        if key in self.__all_slots__:
            return True
        return False

    def __eq__(self, other):
        # special None/False value handling
        for key in self.__all_slots__:
            if key in other.__all_slots__:
                if getattr(self, key) != getattr(other, key):
                    return False
            else:
                return False
        return True

    def __ne__(self, other):
        return not self.__eq__(other)

    def keys(self):
        # special None/False value handling
        return [key for key in self.__all_slots__]

    def values(self):
        # special None/False value handling
        return [getattr(self, key) for key in self.__all_slots__]

    def items(self):
        return tuple([(key, getattr(self, key)) for key in self.__all_slots__])

    has_key = __contains__

    def set_if_none(self, key, value):
        """
        Set the value of key, only if it's not set or None
        """
        if not key in self:
            setattr(self, key, value)

    def set_if_value_not_none(self, key, value):
        """
        Set the value of key, only if value is not None
        """
        if value:
            setattr(self, key, value)

    def __str__(self):
        """
        Guarantee return of string format dictionary representation
        """
        acceptable_types = (str, unicode, int, float, long)
        return str(dict([(key, getattr(self, key))
                         for key in self.__all_slots__
                         if issubclass(type(getattr(self, key)),
                                       acceptable_types)]))

    __repr__ = __str__


class D(PropCan, CopySlots):
    __slots__ = ['_x', 'y']

    @property
    def x(self):
        """ aaaa """
        print "Get"
        return self._x

    @x.setter
    def x(self, value):
        print "Set"
        self._x = value

    @x.deleter
    def x(self):
        del self._x

    def __getstate__(self):
        state = {}
        for slot in self.__slots__:
            state[slot] = getattr(self, slot)
        return state

    def __setstate__(self, state):
        for key, value in state.items():
            setattr(self, key, value)


c = C()
c.x = 4
c.y = 6
print c.x
print c.y
print c

d = D()
d.x = 4
d.y = 6
print len(d)
print d.x
print d.y
print d

a = cPickle.dumps(d)

e = d.copy()
print e.x
print e.y
print e

f = cPickle.loads(a)
print f.x
print f.y
print f

print "_x" in f
print f == e
print len(f)
print f.keys()
print f.values()
_______________________________________________
Virt-test-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/virt-test-devel

Reply via email to