By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
444,034 Members | 1,325 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 444,034 IT Pros & Developers. It's quick & easy.

Best way to control assignment to attribute?

P: n/a
Hi all

I want to control the assignment of a value to an attribute. Instead
of allowing it to be changed directly, I want to enforce that a method
is called, which will perform the assignment subject to various
checks.

From reading the manuals, this is one way to do it.

class frank:
def __init__(self,x):
self.setval_x(x)

def __setattr__(self,name,value):
if name == 'x':
raise 'cannot change value of x - use setval_x(value)'
else:
self.__dict__[name] = value

def setval_x(self,value):
ok = 1
# perform any checks required
if ok:
self.__dict__['x'] = value

Is this the best way, or does anyone have any other suggestions?

I notice that an application can beat this by using the __dict__
syntax itself. Is there any way to prevent this? Just curious, it is
not a major concern.

Any comments will be appreciated.

Thanks

Frank Millman
Jul 18 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Frank Millman wrote:
Hi all

I want to control the assignment of a value to an attribute. Instead
of allowing it to be changed directly, I want to enforce that a method
is called, which will perform the assignment subject to various
checks.

From reading the manuals, this is one way to do it.

class frank:
def __init__(self,x):
self.setval_x(x)

def __setattr__(self,name,value):
if name == 'x':
raise 'cannot change value of x - use setval_x(value)'
I think you shouldn't use string exceptions in new code anymore.
else:
self.__dict__[name] = value

def setval_x(self,value):
ok = 1
# perform any checks required
if ok:
self.__dict__['x'] = value

Is this the best way, or does anyone have any other suggestions?

I notice that an application can beat this by using the __dict__
syntax itself. Is there any way to prevent this? Just curious, it is
not a major concern.

Any comments will be appreciated.

Thanks

Frank Millman


Use new style classes and properties:
class Frank(object): .... def __init__(self, x):
.... self.x = x
.... def getX(self):
.... return self._x
.... def setX(self, x):
.... if x < 0:
.... raise ValueError("x must be >= 0")
.... self._x = x
.... x = property(getX, setX)
.... f = Frank(3)
f.x = 2
f.x = -2

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 8, in setX
ValueError: x must be >= 0

The main advantage is cleaner code, which will become more obvious as the
number of special attributes increases. Also, checked and normal attribute
access is transparent to the client.

Peter

Jul 18 '05 #2

P: n/a
Frank Millman wrote:
I want to control the assignment of a value to an attribute. Instead
of allowing it to be changed directly, I want to enforce that a method
is called, which will perform the assignment subject to various
checks.


I think it is possible with new-style classes, introduced in Python 2.2.

http://users.rcn.com/python/download/Descriptor.htm
http://www.python.org/2.2.2/descrintro.html

Gerrit.

--
PrePEP: Builtin path type
http://people.nl.linux.org/~gerrit/c.../pep-xxxx.html
Asperger's Syndrome - a personal approach:
http://people.nl.linux.org/~gerrit/english/

Jul 18 '05 #3

P: n/a
Frank,
See __slots__; not sure if there's a newer/better way.

wes

Frank Millman wrote:
Hi all

I want to control the assignment of a value to an attribute. Instead
of allowing it to be changed directly, I want to enforce that a method
is called, which will perform the assignment subject to various
checks.

From reading the manuals, this is one way to do it.

class frank:
def __init__(self,x):
self.setval_x(x)

def __setattr__(self,name,value):
if name == 'x':
raise 'cannot change value of x - use setval_x(value)'
else:
self.__dict__[name] = value

def setval_x(self,value):
ok = 1
# perform any checks required
if ok:
self.__dict__['x'] = value

Is this the best way, or does anyone have any other suggestions?

I notice that an application can beat this by using the __dict__
syntax itself. Is there any way to prevent this? Just curious, it is
not a major concern.

Any comments will be appreciated.

Thanks

Frank Millman


Jul 18 '05 #4

P: n/a
In article <XF**********************@bgtnsc05-news.ops.worldnet.att.net>,
wes weston <ww*****@att.net> wrote:
Frank Millman wrote:

I want to control the assignment of a value to an attribute. Instead
of allowing it to be changed directly, I want to enforce that a method
is called, which will perform the assignment subject to various
checks.


See __slots__; not sure if there's a newer/better way.


You should be certain before even thinking of suggesting __slots__.
__slots__ is intended only to save memory; there are many problems with
using it if you don't know what you're doing.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"The joy of coding Python should be in seeing short, concise, readable
classes that express a lot of action in a small amount of clear code --
not in reams of trivial code that bores the reader to death." --GvR
Jul 18 '05 #5

P: n/a
Aahz,
He might be more interested in naming his class vars
with two leading underscores. eh? This mangles the name
making it not as it appears in the text and not accessible
by the expressed name. Does not the __slots__ statement
keep "you" from creating a new unintended class var?
wes

Aahz wrote:
In article <XF**********************@bgtnsc05-news.ops.worldnet.att.net>,
wes weston <ww*****@att.net> wrote:
Frank Millman wrote:
I want to control the assignment of a value to an attribute. Instead
of allowing it to be changed directly, I want to enforce that a method
is called, which will perform the assignment subject to various
checks.


See __slots__; not sure if there's a newer/better way.

You should be certain before even thinking of suggesting __slots__.
__slots__ is intended only to save memory; there are many problems with
using it if you don't know what you're doing.


Jul 18 '05 #6

P: n/a
Wes, please don't top-post. Consider the following:

A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet?

In article <vX*********************@bgtnsc04-news.ops.worldnet.att.net>,
wes weston <ww*****@att.net> wrote:
Aahz wrote:
In article <XF**********************@bgtnsc05-news.ops.worldnet.att.net>,
wes weston <ww*****@att.net> wrote:
Frank Millman wrote:

I want to control the assignment of a value to an attribute. Instead
of allowing it to be changed directly, I want to enforce that a method
is called, which will perform the assignment subject to various
checks.

See __slots__; not sure if there's a newer/better way.


You should be certain before even thinking of suggesting __slots__.
__slots__ is intended only to save memory; there are many problems with
using it if you don't know what you're doing.


He might be more interested in naming his class vars with two leading
underscores. eh? This mangles the name making it not as it appears
in the text and not accessible by the expressed name. Does not the
__slots__ statement keep "you" from creating a new unintended class
var?


Two leading underscores would be good, but it doesn't directly solve the
problem about controlling access to the attribute. Yes, __slots__
prevents the creation of unintended attributes, but it also has other --
frequently undesirable -- consequences. I encourage you to look up some
of the old threads in Google.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"The joy of coding Python should be in seeing short, concise, readable
classes that express a lot of action in a small amount of clear code --
not in reams of trivial code that bores the reader to death." --GvR
Jul 18 '05 #7

P: n/a
fr***@chagford.com (Frank Millman) wrote:
Hi all

I want to control the assignment of a value to an attribute. Instead
of allowing it to be changed directly, I want to enforce that a method
is called, which will perform the assignment subject to various
checks.


Thanks to everybody for the replies. Clearly property() is the way to
go.

I have avoided new-style classes up to now, as I was waiting for a
real need to use them. Now I have one, so it is time to roll up my
sleeves and get stuck in.

Thanks again.

Frank
Jul 18 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.