Best way to control assignment to attribute?

F

Frank Millman

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
 
P

Peter Otten

Frank said:
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:
.... 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)
....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
 
A

Aahz

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 ([email protected]) <*> 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
 
W

wes weston

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
 
A

Aahz

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?

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 ([email protected]) <*> 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
 
F

Frank Millman

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top