1

I was working on my own descriptor based on the Property example in the docs: https://docs.python.org/3/howto/descriptor.html#properties

But for some reason all my properties are the same.

class Property(object):
    "Emulate PyProperty_Type() in Objects/descrobject.c"

    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
        if doc is None and fget is not None:
            doc = fget.__doc__
        self.__doc__ = doc

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        if self.fget is None:
            raise AttributeError("unreadable attribute")
        return self.fget(obj)

    def __set__(self, obj, value):
        if self.fset is None:
            raise AttributeError("can't set attribute")
        self.fset(obj, value)

    def __delete__(self, obj):
        if self.fdel is None:
            raise AttributeError("can't delete attribute")
        self.fdel(obj)

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

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

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

class Demo(object):

    def __init__(self, a=None, b=None):
        self._a = a
        self._b = b

    @Property
    def a(self):
        return self._a

    @a.setter
    def a(self, a):
        self._a = a

    @Property
    def b(self):
        return self._b

    @b.setter
    def a(self, b):
        self._b = b

d = Demo('4')
print(d.a, d.b)  # None None   (Should be: '4' None ?)
d.a = '3'
print(d.a, d.b)  # 3 3   (Should be: '3' None ?)

Firstly, why do the values passed to the constructor not get set/accessed as I intended? Why does changing a seem to change b too?

1 Answer 1

2

There's a typo in the code. Fixing it produces the expected output.

@b.setter
def a(self, b):
    self._b = b

Should be:

@b.setter
def b(self, b):
    self._b = b
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.