Cajga
Cajga

Reputation: 48

Python property setter/getter reference

I have a class where I have to give back a callback function in the iter function. With attributes and get_... style it is easy:

class Test(object):
    def __init__(self):
        self.attrib = 'bla'

    def get_attrib(self):
        return self.attrib

    def __iter__(self):
        yield ('attrib',self.get_attrib)

    def __str__(self):
        ret = ''
        for one in self:
            ret += '%s: %s\n'%(one[0],one[1]())
        return ret

print(Test())

I would like to be more pythonic and use properties. But how can I do the same with the getter of the propertyr? Because this does not work:

class Test(object):
    def __init__(self):
        self._prop = 'bla'

    @property
    def prop(self):
        return self._prop

    def __iter__(self):
        yield ('prop',self.prop.__get__)

    def __str__(self):
        ret = ''
        for one in self:
            ret += '%s: %s\n'%(one[0],one[1]())
        return ret

print(Test())

I found the following but it requires the object itself as an argument when I call it:

def __iter__(self):
        yield ('prop',self.__class__.prop.__get__)

a = Test()
for one in a:
    print '%s: %s'%(one[0],one[1](a)

UPDATE: I need the setter as well but I wanted to make the example simple enough. So at the end I would like to have something like:

def __iter__(self):
            yield ('prop',self.prop.__get__,self.prop.__set__)

Upvotes: 0

Views: 1865

Answers (3)

Remco Haszing
Remco Haszing

Reputation: 7809

If you want the getter and setter to be callable and accessible as a property, you can do the following

class Test(object):
    def __init__(self):
        self._prop = 'bla'

    def get_prop(self):
        return self._prop

    def set_prop(self, val):
        self._prop = val

    prop = property(get_prop, set_prop)

    def __iter__(self):
        yield ('prop',self.get_prop, self.set_prop)

You can now use

test = Test()
test.prop = 'foo'
print(test.prop)

for a in prop:
    name, getter, setter = a

Upvotes: 1

oefe
oefe

Reputation: 19916

Just use a lambda:

    yield ('prop',lambda: self.prop)

Upvotes: 1

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250951

Simply use self.prop and remove the () call from the iteration. Here self.prop will return the string('bla') itself and you're trying to call __get__ on that string, which results in an error as strings don't have any __get__ attribute.:

def __iter__(self):
    yield ('prop', self.prop)

def __str__(self):
    ret = ''
    for one in self:
        ret += '%s: %s\n' % (one[0],one[1]) #remove () call from here

Here self.prop is equivalent to:

Test.prop.__get__(a)

Update: Don't use @property if you want to call it as a function:

def prop(self):
    return self._prop

def __iter__(self):
    yield ('prop', self.prop)

Upvotes: 0

Related Questions