How can I tell if a subclass of the Expando class has a specific property?
I am creating an application that I want to have an extensible set of properties (each with a RatingProperty). I also want to check that any dynamic properties are of type RatingProperty.
Expando documentation says:
Council. If you want to validate the value of a dynamic property using the Property class, you can instantiate the Property class and call its validate () method on the value.
So, if I want to test a dynamic property, I need to know what the non-dynamic properties of a class are. How can I ask my class what it has defined?
I have considered creating a class method that takes a string and returns true if that string is in the list of property names that I create and maintain, but this seems like a hack. I have searched for clues on Google but no luck.
Thanks Pat
source to share
After a bit more research (damn lazyweb!) I found a solution that I think is acceptable:
A dynamic property cannot be of the db subclass property type. Thus, there are two different steps to be taken. First you need to instantiate your property class and validate your value:
test = db.RatingProperty()
if test.validate(valueToSave):
#do your thing
Next, you need to check if the property you want to keep is a declared property:
if valueToSaveKey not in myObject.properties():
#if not save it as desired
myObject.valueToSaveKey = valueToSave
The downside here is that the value you store is not stored as the type of property you want.
source to share
http://code.google.com/appengine/docs/python/datastore/modelclass.html#Model_properties
db.Model has methods for defining all properties of an instance.
The class provides a list of Property objects: db.Model.properties ()
The instance only provides dynamic names: instance.dynamic_properties ()
You want to loop over the list and create property objects, then run p.validate ().
for p_name in instance.dynamic_properties():
p = db.RatingProperty()
p.validate() # raises BadValueError, etc.
source to share
It's actually pretty simple!
ExpandoObject implements (IDictionary<String, Object>)
, so you just need to do this:
dynamic person = new ExpandoObject();
person.FirstName = "Barack";
person.LastName = "Obama"
(((IDictionary<String, Object>)person).Keys
=> { "FirstName", "LastName" }
(((IDictionary<String, Object>)person).ContainsKey("FirstName")
=> true
Note. You need to explicitly point to (IDictionary<string, object>
, because ExpandoObject explicitly implements this interface - and the instance itself does not have an ContainsKey()
or Keys
.
Don't expect this method to work with all dynamic objects - just ExpandoObject and anything that implements this interface.
source to share