Setter definition is shorter

Currently, when I want to define a setter and leave the getter alone, I do this:

@property def my_property(self): return self._my_property @my_property.setter def my_property(self, value): value.do_some_magic() self._my_property = value 

Is there any way to make it shorter? I would like to skip this part as it always looks the same:

 @property def my_property(self): return self._my_property 
+7
python
source share
4 answers

You can make a decorator that automatically creates a getter, following the principle of underlining:

 def setter(fn): def _get(self): return getattr(self, '_' + fn.__name__) def _set(self, val): return fn(self, val) return property(_get, _set) 

or more succinctly if you like this style more:

 def setter(fn): return property( lambda self: getattr(self, '_' + fn.__name__), fn) 

Using:

 class X(object): @setter def my_property(self, value): self._my_property = value + 1 x = X() x.my_property = 42 print x.my_property # 43 
+5
source share

There is no solution, but you can try something like this:

 def defprop(name): def getter(self): return getattr(self, name) return property(getter) class C(object): # ... my_dictionary = defprop('_my_dictionary') # ... 

This does not save you from many keystrokes, but you still have to duplicate the attribute name. In addition, it is less explicit.


Update: With a little thought, I came up with a descriptor-based hacker trick (disclaimer: this is only for demonstration, I do not mean that it is good practice if you have no damn good reason to do this):

 class with_default_getter(object): def __init__(self, func): self._attr_name = '_{0.__name__}'.format(func) self._setter = func def __get__(self, obj, type): return getattr(obj, self._attr_name) def __set__(self, obj, value): return self._setter(obj, value) 

Using:

 class C(object): @with_default_getter def my_property(self, value): print 'setting %s' self._my_property = value >>> c = C() >>> c.my_property = 123 setting 123 >>> c.my_property 123 

This is almost the same as @georg suggests, just expands the implementation to descriptors.

+6
source share

There is no shortcut that I know of - remember that explicit is better than implicit (from Zen python).

It may be that in your code so far the property has always been like this - but at some point you could write aa getter property that gets the fully calculated value - in this case your getter and setter of your property will not look like this everything.

If you said you could write a shell that provides these simple default methods as part of the shell if you want.

+1
source share
 def set_my_property(self, value): value.do_some_magic() self._my_property = value my_property = property(fset=set_my_property) 
+1
source share

All Articles