[Tutor] Re: __setattr__ for dictionary???
Runsun Pan
runsun@bilbo.bio.purdue.edu
Sun Nov 10 13:34:01 2002
hi Emile,
thx for your help but your example is not exactly what i want.
What I want to verify is the value(s) of a dictionary, like 'lee'
, 'john' in the dictionary username={'last':'lee', 'first':'john'}
before the assignment.
When we use __setattr__(self, name, value) for 'username',
the arguements past are:
name = 'username'
value= {'last':'lee', 'first':'john'}
The code in your validationTable:
'family': lambda value: type(value) is dict
only verifies "IF the input valur IS a dict," but didn't go
check if the individual values in this 'input dictionary'
are valid.
The other code in the validationTable,
validationTable = {'son': ismale,
'brother': ismale,
'father': ismale,
'uncle': ismale,
'daughter': isfemale,
'sister': isfemale,
....
does check these properties but these properties are the
'class-level' properties --- they belong to the class,
not members of a dictionary. So it is not the solution to my
question.
pan
(1)
In my original idea,
On Sun, 10 Nov 2002, Emile van Sebille wrote:
] Hi,
]
] Runsun Pan:
] >
] > No it didn't. The code you gave:
] >
] > a.family['uncle']='sam'
] >
] > didn't go through the __setattr__ so I have no
]
] Well, it _did_ go through __setattr__, we just didn't trap it.
]
] > way to verify if the value 'sam' is valid before
] > it is assigned to the 'uncle' key in the 'family'
] > dictionary.
]
] Suppose then (as I'm still unclear on your _desired_ functionality) that
] you want to allow only specific 'uncle'-like keys, each with specific
] validation routines. One way to do this is to create a validation
] dictionary of allowable keys and associated validation functions:
]
] malenames = 'John, Bob, Tom, Ted'.split(', ')
] femalenames = 'Alice, Susan, Sally, Sharon'.split(', ')
]
] def ismale(value):
] return value in malenames
]
] def isfemale(value):
] return value in femalenames
]
] def anyvalue(value): return True
]
] validationTable = {'son': ismale,
] 'brother': ismale,
] 'father': ismale,
] 'uncle': ismale,
] 'daughter': isfemale,
] 'sister': isfemale,
] 'mother': isfemale,
] 'aunt': isfemale,
] 'name': anyvalue,
] 'family': lambda value: type(value) is dict,
] 'height': lambda value: type(value) is int}
]
]
] Then modify __setattr__ to to the right thing::
]
] class myclass:
] def __init__(self):
] self.__dict__['name']={'last':'lee', 'first':'john'}
] self.__dict__['family']={'brother':2, 'sister':1}
] self.__dict__['height']=170
] def __setattr__(self,name,value):
] if validationTable.has_key(name):
] print 'setting name'
] if validationTable[name](value):
] # now both the name and value are good
] # store it in the appropriate place
] self.__dict__[name] = value
] else: raise ValueError, 'Inappropriate value (%s) passed for
] key (%s)' %(value, name)
] else: raise KeyError, 'Name not allowed (%s)' % name
]
] Now lets see if it works:
]
] >>> a = myclass()
] >>> a.height='hello' # it shouldn't take a string value
] setting name
] Traceback (most recent call last):
] File "<stdin>", line 1, in ?
] File "<stdin>", line 13, in __setattr__
] ValueError: Inappropriate value (hello) passed for key (height)
] >>> a.height=182 # so far so good...
] setting name
]
]
]
] >>> a.gramma = 'Emma'
] Traceback (most recent call last):
] File "<stdin>", line 1, in ?
] File "<stdin>", line 14, in __setattr__
] KeyError: Name not allowed (gramma)
] >>> a.aunt = 'Emma'
] setting name
] Traceback (most recent call last):
] File "<stdin>", line 1, in ?
] File "<stdin>", line 13, in __setattr__
] ValueError: Inappropriate value (Emma) passed for key (aunt)
] >>> a.aunt = 'Sally'
] setting name
] >>> a.aunt
] 'Sally'
] >>> a.family
] {'sister': 1, 'brother': 2}
] >>> a.family = 'hello'
] setting name
] Traceback (most recent call last):
] File "<stdin>", line 1, in ?
] File "<stdin>", line 13, in __setattr__
] ValueError: Inappropriate value (hello) passed for key (family)
] >>>
]
]
] >
] > The __setattr__ only works for a single-value
]
] if works _only_ as you program it to. I programmed it to follow your
] example thinking it to be the best presentation of your intent, and I
] imagined that my example would be extrapolated upon. I continue to
] assume that now: you can add further validation routines, or otherwise
] expand upon what I've done to make it fit your requirements.
]
]
] --
]
] Emile van Sebille
] emile@fenx.com
]
] ---------
]
--
========================================
---> Be like water, be shapeless <---
Runsun Pan, PhD
Ecology & Evolution, U. of Chicago
========================================