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

0


source to share


4 answers


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.

+1


source


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.

      

+1


source


I may not understand your question, but if you have a list of properties that you expect to find, why not just use the standard db.Model instead of Expando? You can add additional properties to the Model class if you either provide the default or don't require them.

0


source


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.

0


source







All Articles