[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
 ========================================