0

I'm trying to use properties and I tried to change python documentation's code. I'd expect the following would print anything, but it doesn't. Why does it not print anything?

class User:
    def getter(self, name):
        def get_prop(self):
            print 'Getting {}'.format(name)
            return getattr(self, name)
        return get_prop

    def setter(self, name):
        def set_prop(self, value):
            print 'Setting {} to {}'.format(name, value)
            return setattr(self, name, value)
        return set_prop

    user_id = property(getter, setter)


u = User()
u.user_id = 10
u.user_id
duality_
  • 17,738
  • 23
  • 77
  • 95
  • 1
    I get `10` when I `print u.user_id`, or `TypeError` if you make `User` inherit from `object`. Note that you never actually *call* either of the functions that involve `print`. – jonrsharpe Nov 10 '14 at 14:10

2 Answers2

2

There are two reasons your property doesn't work:

  1. You need to use a new style class (by basing your class on object); you cannot use a property with a setter otherwise (only a getter is supported for old-style classes).

  2. you are generating accessors as nested functions; you need to call those outer methods to generate those accessors, the property() function will no do this for you. As such, you can move those functions out of the class and use them as plain functions instead.

The following code works:

def getter(name):
    def get_prop(self):
        print 'Getting {}'.format(name)
        return getattr(self, name)
    return get_prop

def setter(name):
    def set_prop(self, value):
        print 'Setting {} to {}'.format(name, value)
        return setattr(self, name, value)
    return set_prop

class User(object):
    user_id = property(getter('_user_id'), setter('_user_id'))

Note that I used _user_id for the property 'name' here, otherwise the getattr(self, name) call will trigger an infinite recursion; u.user_id would trigger a getattr(u, 'user_id') which triggers the property again.

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

Probably because properties only work with new-style objects. Change your class statement to:

class User(object):

Looking further, your getter and setter functions are returning functions, that you then do not call.

You seem to want dynamic attribute names, yet you have just one attribute name returned from property, in your case this is user_id. What is it you are trying to achieve?

cdarke
  • 42,728
  • 8
  • 80
  • 84
  • Wow, didn't know about that, thank you. Yeah, I had to do some further refactoring, now it works with this code: https://gist.github.com/rokcarl/900e0b96cf75af126f9b. – duality_ Nov 10 '14 at 14:16