如何判断Expando子类是否定义了属性?

时间:2009-01-06 18:14:01

标签: python google-app-engine

我正在创建一个应用程序,我希望有一组可扩展的属性(每个属性为RatingProperty)我还想验证任何动态属性是RatingProperty类型。

在Expando文档中,它说:

  

提示:如果要使用Property类验证动态属性值,可以实例化Property类并对值调用其validate()方法。

因此,如果我想验证动态属性,我需要知道该类的非动态属性是什么。我怎么能问我的班级它的定义属性是什么?

我考虑创建一个接受字符串的类方法,如果该字符串位于我创建和维护的属性名称列表中,则返回true,但它看起来像是一个黑客。我在Google上搜索了一些提示,但没有运气。

谢谢, 专利

4 个答案:

答案 0 :(得分:1)

经过一番研究(该死的懒鬼!)我找到了一个我认为可以接受的解决方案:

动态属性不能是db子类属性类型。因此,必须采取两个不同的步骤。首先,您需要创建属性类的实例并验证您的值:

test = db.RatingProperty()
if test.validate(valueToSave):
    #do your thing

接下来,您需要检查要保存的属性是否为声明的属性:

if valueToSaveKey not in myObject.properties():
    #if not save it as desired
    myObject.valueToSaveKey = valueToSave

这里的缺点是您保存的值不会存储为您想要的属性类型。

答案 1 :(得分:1)

http://code.google.com/appengine/docs/python/datastore/modelclass.html#Model_properties

db.Model具有查找实例上所有属性的方法。

该类公开了一个Property对象列表:db.Model.properties()

实例仅公开动态名称:instance.dynamic_properties()

您希望遍历列表并构建Property对象,然后运行p.validate()。

for p_name in instance.dynamic_properties():
    p = db.RatingProperty()
    p.validate() # raises BadValueError, etc.

答案 2 :(得分:0)

我可能误解了你的问题,但是如果你有一个你希望找到的属性列表,为什么不使用标准的db.Model而不是Expando?您可以向Model类添加其他属性,只要您提供默认值或不需要它们。

答案 3 :(得分:0)

实际上很容易!

ExpandoObject实施(IDictionary<String, Object>)所以你只需要这样做:

 dynamic person = new ExpandoObject();
 person.FirstName = "Barack";
 person.LastName = "Obama"

 (((IDictionary<String, Object>)person).Keys  
    => { "FirstName", "LastName" }

 (((IDictionary<String, Object>)person).ContainsKey("FirstName")  
    => true

注意:您需要显式转换为(IDictionary<string, object>,因为ExpandoObject显式实现了此接口 - 并且实例本身没有ContainsKey()Keys

不要指望此方法适用于所有动态对象 - 只需要ExpandoObject和其他任何实现此接口的方法。