Python class @property: use setter but evade getter?
In python classes, the @property is a nice decorator that avoids using explicit setter and getter functions. However, it comes at a cost of an overhead 2-5 times that of a "classical" class function. In my case, this is quite OK in the case of setting a property, where the overhead is insignificant compared to the processing that needs to be done when setting.
However, I need no processing when getting the property. It is always just "return self.property". Is there an elegant way to use the setter but not using the getter, without needing to use a different internal variable?
Just to illustrate, the class below has the property "var" which refers to the internal variable "_var". It takes longer to call "var" than "_var" but it would be nice if developers and users alike could just use "var" without having to keep track of "_var" too.
class MyClass(object):
def __init__(self):
self._var = None
# the property "var". First the getter, then the setter
@property
def var(self):
return self._var
@var.setter
def var(self, newValue):
self._var = newValue
#... and a lot of other stuff here
# Use "var" a lot! How to avoid the overhead of the getter and not to call self._var!
def useAttribute(self):
for i in xrange(100000):
self.var == 'something'
For those interested, on my pc calling "var" takes 204 ns on average while calling "_var" takes 44 ns on average.
python class properties timing
add a comment |
In python classes, the @property is a nice decorator that avoids using explicit setter and getter functions. However, it comes at a cost of an overhead 2-5 times that of a "classical" class function. In my case, this is quite OK in the case of setting a property, where the overhead is insignificant compared to the processing that needs to be done when setting.
However, I need no processing when getting the property. It is always just "return self.property". Is there an elegant way to use the setter but not using the getter, without needing to use a different internal variable?
Just to illustrate, the class below has the property "var" which refers to the internal variable "_var". It takes longer to call "var" than "_var" but it would be nice if developers and users alike could just use "var" without having to keep track of "_var" too.
class MyClass(object):
def __init__(self):
self._var = None
# the property "var". First the getter, then the setter
@property
def var(self):
return self._var
@var.setter
def var(self, newValue):
self._var = newValue
#... and a lot of other stuff here
# Use "var" a lot! How to avoid the overhead of the getter and not to call self._var!
def useAttribute(self):
for i in xrange(100000):
self.var == 'something'
For those interested, on my pc calling "var" takes 204 ns on average while calling "_var" takes 44 ns on average.
python class properties timing
1
No, there isn't such a way. Once you use a data descriptor, instance attributes of the same name are not honoured.
– Martijn Pieters♦
Jul 10 '13 at 16:28
add a comment |
In python classes, the @property is a nice decorator that avoids using explicit setter and getter functions. However, it comes at a cost of an overhead 2-5 times that of a "classical" class function. In my case, this is quite OK in the case of setting a property, where the overhead is insignificant compared to the processing that needs to be done when setting.
However, I need no processing when getting the property. It is always just "return self.property". Is there an elegant way to use the setter but not using the getter, without needing to use a different internal variable?
Just to illustrate, the class below has the property "var" which refers to the internal variable "_var". It takes longer to call "var" than "_var" but it would be nice if developers and users alike could just use "var" without having to keep track of "_var" too.
class MyClass(object):
def __init__(self):
self._var = None
# the property "var". First the getter, then the setter
@property
def var(self):
return self._var
@var.setter
def var(self, newValue):
self._var = newValue
#... and a lot of other stuff here
# Use "var" a lot! How to avoid the overhead of the getter and not to call self._var!
def useAttribute(self):
for i in xrange(100000):
self.var == 'something'
For those interested, on my pc calling "var" takes 204 ns on average while calling "_var" takes 44 ns on average.
python class properties timing
In python classes, the @property is a nice decorator that avoids using explicit setter and getter functions. However, it comes at a cost of an overhead 2-5 times that of a "classical" class function. In my case, this is quite OK in the case of setting a property, where the overhead is insignificant compared to the processing that needs to be done when setting.
However, I need no processing when getting the property. It is always just "return self.property". Is there an elegant way to use the setter but not using the getter, without needing to use a different internal variable?
Just to illustrate, the class below has the property "var" which refers to the internal variable "_var". It takes longer to call "var" than "_var" but it would be nice if developers and users alike could just use "var" without having to keep track of "_var" too.
class MyClass(object):
def __init__(self):
self._var = None
# the property "var". First the getter, then the setter
@property
def var(self):
return self._var
@var.setter
def var(self, newValue):
self._var = newValue
#... and a lot of other stuff here
# Use "var" a lot! How to avoid the overhead of the getter and not to call self._var!
def useAttribute(self):
for i in xrange(100000):
self.var == 'something'
For those interested, on my pc calling "var" takes 204 ns on average while calling "_var" takes 44 ns on average.
python class properties timing
python class properties timing
asked Jul 10 '13 at 16:26
Jonas LindeløvJonas Lindeløv
3,03451841
3,03451841
1
No, there isn't such a way. Once you use a data descriptor, instance attributes of the same name are not honoured.
– Martijn Pieters♦
Jul 10 '13 at 16:28
add a comment |
1
No, there isn't such a way. Once you use a data descriptor, instance attributes of the same name are not honoured.
– Martijn Pieters♦
Jul 10 '13 at 16:28
1
1
No, there isn't such a way. Once you use a data descriptor, instance attributes of the same name are not honoured.
– Martijn Pieters♦
Jul 10 '13 at 16:28
No, there isn't such a way. Once you use a data descriptor, instance attributes of the same name are not honoured.
– Martijn Pieters♦
Jul 10 '13 at 16:28
add a comment |
2 Answers
2
active
oldest
votes
Don't use a property in this case. A property object is a data descriptor, which means that any access to instance.var will invoke that descriptor and Python will never look for an attribute on the instance itself.
You have two options: use the .__setattr__() hook or build a descriptor that only implements .__set__.
Using the .__setattr__() hook
class MyClass(object):
var = 'foo'
def __setattr__(self, name, value):
if name == 'var':
print "Setting var!"
# do something with `value` here, like you would in a
# setter.
value = 'Set to ' + value
super(MyClass, self).__setattr__(name, value)
Now normal attribute lookups are used when reading .var but when assigning to .var the __setattr__ method is invoked instead, letting you intercept value and adjust it as needed.
Demo:
>>> mc = MyClass()
>>> mc.var
'foo'
>>> mc.var = 'bar'
Setting var!
>>> mc.var
'Set to bar'
A setter descriptor
A setter descriptor would only intercept variable assignment:
class SetterProperty(object):
def __init__(self, func, doc=None):
self.func = func
self.__doc__ = doc if doc is not None else func.__doc__
def __set__(self, obj, value):
return self.func(obj, value)
class Foo(object):
@SetterProperty
def var(self, value):
print 'Setting var!'
self.__dict__['var'] = value
Note how we need to assign to the instance .__dict__ attribute to prevent invoking the setter again.
Demo:
>>> f = Foo()
>>> f.var = 'spam'
Setting var!
>>> f.var = 'ham'
Setting var!
>>> f.var
'ham'
>>> f.var = 'biggles'
Setting var!
>>> f.var
'biggles'
Thanks a lot for a great response! I ended up using the setattr hook because only it allowed operations on the value like "myInstance.attrib += 5". I can add that the setattr is not overwritten if it is set in a class that extends another class. In terms of performance it adds around x3 overhead compared to @property setter, but of cause it is much faster to get an attribute value, which is way more important.
– Jonas Lindeløv
Jul 10 '13 at 19:34
Quick question. Would it work if you movedself.__dict__['var'] = valueto the descriptor's__set__method asobj.__dict__['var'] = value?
– Mad Physicist
Dec 16 '16 at 16:27
@MadPhysicist: of course!selfandobjreference the same object there.
– Martijn Pieters♦
Dec 16 '16 at 16:31
And more generally, could you doobj.__dict__[self.func.__name__] = value? Am I correct in expecting this to work whenever the annotated method is defined viadef?
– Mad Physicist
Dec 16 '16 at 16:34
1
Also related: docs.python.org/3.6/whatsnew/…
– Mad Physicist
Dec 22 '16 at 21:47
|
show 3 more comments
property python docs: https://docs.python.org/2/howto/descriptor.html#properties
class MyClass(object):
def __init__(self):
self._var = None
# only setter
def var(self, newValue):
self._var = newValue
var = property(None, var)
c = MyClass()
c.var = 3
print ('ok')
print (c.var)
output:
ok
Traceback (most recent call last):
File "Untitled.py", line 15, in <module>
print c.var
AttributeError: unreadable attribute
2
This does not solve the problem since I still want the attribute to be "gettable". It's just that I didn't want any processing overhead on getting it. But interesting solution for other purposes!
– Jonas Lindeløv
Jan 29 '16 at 23:03
1
@JonasLindeløv Yes, this may be useful for someone, so I posted my answer here.
– WeizhongTu
Jan 30 '16 at 7:25
@WeizhongTu it is, thanks.
– max
Mar 8 '17 at 10:18
is there any way I can use this as decorator. I mean rather than usingvar = property(None, var), I use decorator
– Gaurang Shah
Aug 18 '17 at 14:27
1
@WeizhongTu You can make the attribute readable by replacingvar = property(None, var)withvar = property(lambda x: x._var, var).
– Nuno André
Sep 20 '17 at 22:55
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f17576009%2fpython-class-property-use-setter-but-evade-getter%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Don't use a property in this case. A property object is a data descriptor, which means that any access to instance.var will invoke that descriptor and Python will never look for an attribute on the instance itself.
You have two options: use the .__setattr__() hook or build a descriptor that only implements .__set__.
Using the .__setattr__() hook
class MyClass(object):
var = 'foo'
def __setattr__(self, name, value):
if name == 'var':
print "Setting var!"
# do something with `value` here, like you would in a
# setter.
value = 'Set to ' + value
super(MyClass, self).__setattr__(name, value)
Now normal attribute lookups are used when reading .var but when assigning to .var the __setattr__ method is invoked instead, letting you intercept value and adjust it as needed.
Demo:
>>> mc = MyClass()
>>> mc.var
'foo'
>>> mc.var = 'bar'
Setting var!
>>> mc.var
'Set to bar'
A setter descriptor
A setter descriptor would only intercept variable assignment:
class SetterProperty(object):
def __init__(self, func, doc=None):
self.func = func
self.__doc__ = doc if doc is not None else func.__doc__
def __set__(self, obj, value):
return self.func(obj, value)
class Foo(object):
@SetterProperty
def var(self, value):
print 'Setting var!'
self.__dict__['var'] = value
Note how we need to assign to the instance .__dict__ attribute to prevent invoking the setter again.
Demo:
>>> f = Foo()
>>> f.var = 'spam'
Setting var!
>>> f.var = 'ham'
Setting var!
>>> f.var
'ham'
>>> f.var = 'biggles'
Setting var!
>>> f.var
'biggles'
Thanks a lot for a great response! I ended up using the setattr hook because only it allowed operations on the value like "myInstance.attrib += 5". I can add that the setattr is not overwritten if it is set in a class that extends another class. In terms of performance it adds around x3 overhead compared to @property setter, but of cause it is much faster to get an attribute value, which is way more important.
– Jonas Lindeløv
Jul 10 '13 at 19:34
Quick question. Would it work if you movedself.__dict__['var'] = valueto the descriptor's__set__method asobj.__dict__['var'] = value?
– Mad Physicist
Dec 16 '16 at 16:27
@MadPhysicist: of course!selfandobjreference the same object there.
– Martijn Pieters♦
Dec 16 '16 at 16:31
And more generally, could you doobj.__dict__[self.func.__name__] = value? Am I correct in expecting this to work whenever the annotated method is defined viadef?
– Mad Physicist
Dec 16 '16 at 16:34
1
Also related: docs.python.org/3.6/whatsnew/…
– Mad Physicist
Dec 22 '16 at 21:47
|
show 3 more comments
Don't use a property in this case. A property object is a data descriptor, which means that any access to instance.var will invoke that descriptor and Python will never look for an attribute on the instance itself.
You have two options: use the .__setattr__() hook or build a descriptor that only implements .__set__.
Using the .__setattr__() hook
class MyClass(object):
var = 'foo'
def __setattr__(self, name, value):
if name == 'var':
print "Setting var!"
# do something with `value` here, like you would in a
# setter.
value = 'Set to ' + value
super(MyClass, self).__setattr__(name, value)
Now normal attribute lookups are used when reading .var but when assigning to .var the __setattr__ method is invoked instead, letting you intercept value and adjust it as needed.
Demo:
>>> mc = MyClass()
>>> mc.var
'foo'
>>> mc.var = 'bar'
Setting var!
>>> mc.var
'Set to bar'
A setter descriptor
A setter descriptor would only intercept variable assignment:
class SetterProperty(object):
def __init__(self, func, doc=None):
self.func = func
self.__doc__ = doc if doc is not None else func.__doc__
def __set__(self, obj, value):
return self.func(obj, value)
class Foo(object):
@SetterProperty
def var(self, value):
print 'Setting var!'
self.__dict__['var'] = value
Note how we need to assign to the instance .__dict__ attribute to prevent invoking the setter again.
Demo:
>>> f = Foo()
>>> f.var = 'spam'
Setting var!
>>> f.var = 'ham'
Setting var!
>>> f.var
'ham'
>>> f.var = 'biggles'
Setting var!
>>> f.var
'biggles'
Thanks a lot for a great response! I ended up using the setattr hook because only it allowed operations on the value like "myInstance.attrib += 5". I can add that the setattr is not overwritten if it is set in a class that extends another class. In terms of performance it adds around x3 overhead compared to @property setter, but of cause it is much faster to get an attribute value, which is way more important.
– Jonas Lindeløv
Jul 10 '13 at 19:34
Quick question. Would it work if you movedself.__dict__['var'] = valueto the descriptor's__set__method asobj.__dict__['var'] = value?
– Mad Physicist
Dec 16 '16 at 16:27
@MadPhysicist: of course!selfandobjreference the same object there.
– Martijn Pieters♦
Dec 16 '16 at 16:31
And more generally, could you doobj.__dict__[self.func.__name__] = value? Am I correct in expecting this to work whenever the annotated method is defined viadef?
– Mad Physicist
Dec 16 '16 at 16:34
1
Also related: docs.python.org/3.6/whatsnew/…
– Mad Physicist
Dec 22 '16 at 21:47
|
show 3 more comments
Don't use a property in this case. A property object is a data descriptor, which means that any access to instance.var will invoke that descriptor and Python will never look for an attribute on the instance itself.
You have two options: use the .__setattr__() hook or build a descriptor that only implements .__set__.
Using the .__setattr__() hook
class MyClass(object):
var = 'foo'
def __setattr__(self, name, value):
if name == 'var':
print "Setting var!"
# do something with `value` here, like you would in a
# setter.
value = 'Set to ' + value
super(MyClass, self).__setattr__(name, value)
Now normal attribute lookups are used when reading .var but when assigning to .var the __setattr__ method is invoked instead, letting you intercept value and adjust it as needed.
Demo:
>>> mc = MyClass()
>>> mc.var
'foo'
>>> mc.var = 'bar'
Setting var!
>>> mc.var
'Set to bar'
A setter descriptor
A setter descriptor would only intercept variable assignment:
class SetterProperty(object):
def __init__(self, func, doc=None):
self.func = func
self.__doc__ = doc if doc is not None else func.__doc__
def __set__(self, obj, value):
return self.func(obj, value)
class Foo(object):
@SetterProperty
def var(self, value):
print 'Setting var!'
self.__dict__['var'] = value
Note how we need to assign to the instance .__dict__ attribute to prevent invoking the setter again.
Demo:
>>> f = Foo()
>>> f.var = 'spam'
Setting var!
>>> f.var = 'ham'
Setting var!
>>> f.var
'ham'
>>> f.var = 'biggles'
Setting var!
>>> f.var
'biggles'
Don't use a property in this case. A property object is a data descriptor, which means that any access to instance.var will invoke that descriptor and Python will never look for an attribute on the instance itself.
You have two options: use the .__setattr__() hook or build a descriptor that only implements .__set__.
Using the .__setattr__() hook
class MyClass(object):
var = 'foo'
def __setattr__(self, name, value):
if name == 'var':
print "Setting var!"
# do something with `value` here, like you would in a
# setter.
value = 'Set to ' + value
super(MyClass, self).__setattr__(name, value)
Now normal attribute lookups are used when reading .var but when assigning to .var the __setattr__ method is invoked instead, letting you intercept value and adjust it as needed.
Demo:
>>> mc = MyClass()
>>> mc.var
'foo'
>>> mc.var = 'bar'
Setting var!
>>> mc.var
'Set to bar'
A setter descriptor
A setter descriptor would only intercept variable assignment:
class SetterProperty(object):
def __init__(self, func, doc=None):
self.func = func
self.__doc__ = doc if doc is not None else func.__doc__
def __set__(self, obj, value):
return self.func(obj, value)
class Foo(object):
@SetterProperty
def var(self, value):
print 'Setting var!'
self.__dict__['var'] = value
Note how we need to assign to the instance .__dict__ attribute to prevent invoking the setter again.
Demo:
>>> f = Foo()
>>> f.var = 'spam'
Setting var!
>>> f.var = 'ham'
Setting var!
>>> f.var
'ham'
>>> f.var = 'biggles'
Setting var!
>>> f.var
'biggles'
edited Jul 10 '13 at 16:42
answered Jul 10 '13 at 16:31
Martijn Pieters♦Martijn Pieters
714k13724952307
714k13724952307
Thanks a lot for a great response! I ended up using the setattr hook because only it allowed operations on the value like "myInstance.attrib += 5". I can add that the setattr is not overwritten if it is set in a class that extends another class. In terms of performance it adds around x3 overhead compared to @property setter, but of cause it is much faster to get an attribute value, which is way more important.
– Jonas Lindeløv
Jul 10 '13 at 19:34
Quick question. Would it work if you movedself.__dict__['var'] = valueto the descriptor's__set__method asobj.__dict__['var'] = value?
– Mad Physicist
Dec 16 '16 at 16:27
@MadPhysicist: of course!selfandobjreference the same object there.
– Martijn Pieters♦
Dec 16 '16 at 16:31
And more generally, could you doobj.__dict__[self.func.__name__] = value? Am I correct in expecting this to work whenever the annotated method is defined viadef?
– Mad Physicist
Dec 16 '16 at 16:34
1
Also related: docs.python.org/3.6/whatsnew/…
– Mad Physicist
Dec 22 '16 at 21:47
|
show 3 more comments
Thanks a lot for a great response! I ended up using the setattr hook because only it allowed operations on the value like "myInstance.attrib += 5". I can add that the setattr is not overwritten if it is set in a class that extends another class. In terms of performance it adds around x3 overhead compared to @property setter, but of cause it is much faster to get an attribute value, which is way more important.
– Jonas Lindeløv
Jul 10 '13 at 19:34
Quick question. Would it work if you movedself.__dict__['var'] = valueto the descriptor's__set__method asobj.__dict__['var'] = value?
– Mad Physicist
Dec 16 '16 at 16:27
@MadPhysicist: of course!selfandobjreference the same object there.
– Martijn Pieters♦
Dec 16 '16 at 16:31
And more generally, could you doobj.__dict__[self.func.__name__] = value? Am I correct in expecting this to work whenever the annotated method is defined viadef?
– Mad Physicist
Dec 16 '16 at 16:34
1
Also related: docs.python.org/3.6/whatsnew/…
– Mad Physicist
Dec 22 '16 at 21:47
Thanks a lot for a great response! I ended up using the setattr hook because only it allowed operations on the value like "myInstance.attrib += 5". I can add that the setattr is not overwritten if it is set in a class that extends another class. In terms of performance it adds around x3 overhead compared to @property setter, but of cause it is much faster to get an attribute value, which is way more important.
– Jonas Lindeløv
Jul 10 '13 at 19:34
Thanks a lot for a great response! I ended up using the setattr hook because only it allowed operations on the value like "myInstance.attrib += 5". I can add that the setattr is not overwritten if it is set in a class that extends another class. In terms of performance it adds around x3 overhead compared to @property setter, but of cause it is much faster to get an attribute value, which is way more important.
– Jonas Lindeløv
Jul 10 '13 at 19:34
Quick question. Would it work if you moved
self.__dict__['var'] = value to the descriptor's __set__ method as obj.__dict__['var'] = value?– Mad Physicist
Dec 16 '16 at 16:27
Quick question. Would it work if you moved
self.__dict__['var'] = value to the descriptor's __set__ method as obj.__dict__['var'] = value?– Mad Physicist
Dec 16 '16 at 16:27
@MadPhysicist: of course!
self and obj reference the same object there.– Martijn Pieters♦
Dec 16 '16 at 16:31
@MadPhysicist: of course!
self and obj reference the same object there.– Martijn Pieters♦
Dec 16 '16 at 16:31
And more generally, could you do
obj.__dict__[self.func.__name__] = value? Am I correct in expecting this to work whenever the annotated method is defined via def?– Mad Physicist
Dec 16 '16 at 16:34
And more generally, could you do
obj.__dict__[self.func.__name__] = value? Am I correct in expecting this to work whenever the annotated method is defined via def?– Mad Physicist
Dec 16 '16 at 16:34
1
1
Also related: docs.python.org/3.6/whatsnew/…
– Mad Physicist
Dec 22 '16 at 21:47
Also related: docs.python.org/3.6/whatsnew/…
– Mad Physicist
Dec 22 '16 at 21:47
|
show 3 more comments
property python docs: https://docs.python.org/2/howto/descriptor.html#properties
class MyClass(object):
def __init__(self):
self._var = None
# only setter
def var(self, newValue):
self._var = newValue
var = property(None, var)
c = MyClass()
c.var = 3
print ('ok')
print (c.var)
output:
ok
Traceback (most recent call last):
File "Untitled.py", line 15, in <module>
print c.var
AttributeError: unreadable attribute
2
This does not solve the problem since I still want the attribute to be "gettable". It's just that I didn't want any processing overhead on getting it. But interesting solution for other purposes!
– Jonas Lindeløv
Jan 29 '16 at 23:03
1
@JonasLindeløv Yes, this may be useful for someone, so I posted my answer here.
– WeizhongTu
Jan 30 '16 at 7:25
@WeizhongTu it is, thanks.
– max
Mar 8 '17 at 10:18
is there any way I can use this as decorator. I mean rather than usingvar = property(None, var), I use decorator
– Gaurang Shah
Aug 18 '17 at 14:27
1
@WeizhongTu You can make the attribute readable by replacingvar = property(None, var)withvar = property(lambda x: x._var, var).
– Nuno André
Sep 20 '17 at 22:55
add a comment |
property python docs: https://docs.python.org/2/howto/descriptor.html#properties
class MyClass(object):
def __init__(self):
self._var = None
# only setter
def var(self, newValue):
self._var = newValue
var = property(None, var)
c = MyClass()
c.var = 3
print ('ok')
print (c.var)
output:
ok
Traceback (most recent call last):
File "Untitled.py", line 15, in <module>
print c.var
AttributeError: unreadable attribute
2
This does not solve the problem since I still want the attribute to be "gettable". It's just that I didn't want any processing overhead on getting it. But interesting solution for other purposes!
– Jonas Lindeløv
Jan 29 '16 at 23:03
1
@JonasLindeløv Yes, this may be useful for someone, so I posted my answer here.
– WeizhongTu
Jan 30 '16 at 7:25
@WeizhongTu it is, thanks.
– max
Mar 8 '17 at 10:18
is there any way I can use this as decorator. I mean rather than usingvar = property(None, var), I use decorator
– Gaurang Shah
Aug 18 '17 at 14:27
1
@WeizhongTu You can make the attribute readable by replacingvar = property(None, var)withvar = property(lambda x: x._var, var).
– Nuno André
Sep 20 '17 at 22:55
add a comment |
property python docs: https://docs.python.org/2/howto/descriptor.html#properties
class MyClass(object):
def __init__(self):
self._var = None
# only setter
def var(self, newValue):
self._var = newValue
var = property(None, var)
c = MyClass()
c.var = 3
print ('ok')
print (c.var)
output:
ok
Traceback (most recent call last):
File "Untitled.py", line 15, in <module>
print c.var
AttributeError: unreadable attribute
property python docs: https://docs.python.org/2/howto/descriptor.html#properties
class MyClass(object):
def __init__(self):
self._var = None
# only setter
def var(self, newValue):
self._var = newValue
var = property(None, var)
c = MyClass()
c.var = 3
print ('ok')
print (c.var)
output:
ok
Traceback (most recent call last):
File "Untitled.py", line 15, in <module>
print c.var
AttributeError: unreadable attribute
edited Nov 21 '16 at 12:33
answered Jan 27 '16 at 9:41
WeizhongTuWeizhongTu
2,8992138
2,8992138
2
This does not solve the problem since I still want the attribute to be "gettable". It's just that I didn't want any processing overhead on getting it. But interesting solution for other purposes!
– Jonas Lindeløv
Jan 29 '16 at 23:03
1
@JonasLindeløv Yes, this may be useful for someone, so I posted my answer here.
– WeizhongTu
Jan 30 '16 at 7:25
@WeizhongTu it is, thanks.
– max
Mar 8 '17 at 10:18
is there any way I can use this as decorator. I mean rather than usingvar = property(None, var), I use decorator
– Gaurang Shah
Aug 18 '17 at 14:27
1
@WeizhongTu You can make the attribute readable by replacingvar = property(None, var)withvar = property(lambda x: x._var, var).
– Nuno André
Sep 20 '17 at 22:55
add a comment |
2
This does not solve the problem since I still want the attribute to be "gettable". It's just that I didn't want any processing overhead on getting it. But interesting solution for other purposes!
– Jonas Lindeløv
Jan 29 '16 at 23:03
1
@JonasLindeløv Yes, this may be useful for someone, so I posted my answer here.
– WeizhongTu
Jan 30 '16 at 7:25
@WeizhongTu it is, thanks.
– max
Mar 8 '17 at 10:18
is there any way I can use this as decorator. I mean rather than usingvar = property(None, var), I use decorator
– Gaurang Shah
Aug 18 '17 at 14:27
1
@WeizhongTu You can make the attribute readable by replacingvar = property(None, var)withvar = property(lambda x: x._var, var).
– Nuno André
Sep 20 '17 at 22:55
2
2
This does not solve the problem since I still want the attribute to be "gettable". It's just that I didn't want any processing overhead on getting it. But interesting solution for other purposes!
– Jonas Lindeløv
Jan 29 '16 at 23:03
This does not solve the problem since I still want the attribute to be "gettable". It's just that I didn't want any processing overhead on getting it. But interesting solution for other purposes!
– Jonas Lindeløv
Jan 29 '16 at 23:03
1
1
@JonasLindeløv Yes, this may be useful for someone, so I posted my answer here.
– WeizhongTu
Jan 30 '16 at 7:25
@JonasLindeløv Yes, this may be useful for someone, so I posted my answer here.
– WeizhongTu
Jan 30 '16 at 7:25
@WeizhongTu it is, thanks.
– max
Mar 8 '17 at 10:18
@WeizhongTu it is, thanks.
– max
Mar 8 '17 at 10:18
is there any way I can use this as decorator. I mean rather than using
var = property(None, var) , I use decorator– Gaurang Shah
Aug 18 '17 at 14:27
is there any way I can use this as decorator. I mean rather than using
var = property(None, var) , I use decorator– Gaurang Shah
Aug 18 '17 at 14:27
1
1
@WeizhongTu You can make the attribute readable by replacing
var = property(None, var) with var = property(lambda x: x._var, var).– Nuno André
Sep 20 '17 at 22:55
@WeizhongTu You can make the attribute readable by replacing
var = property(None, var) with var = property(lambda x: x._var, var).– Nuno André
Sep 20 '17 at 22:55
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f17576009%2fpython-class-property-use-setter-but-evade-getter%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
No, there isn't such a way. Once you use a data descriptor, instance attributes of the same name are not honoured.
– Martijn Pieters♦
Jul 10 '13 at 16:28