我正在创建一个应用程序,我希望有一组可扩展的属性(每个属性为RatingProperty)我还想验证任何动态属性是RatingProperty类型。
在Expando文档中,它说:
提示:如果要使用Property类验证动态属性值,可以实例化Property类并对值调用其validate()方法。
因此,如果我想验证动态属性,我需要知道该类的非动态属性是什么。我怎么能问我的班级它的定义属性是什么?
我考虑创建一个接受字符串的类方法,如果该字符串位于我创建和维护的属性名称列表中,则返回true,但它看起来像是一个黑客。我在Google上搜索了一些提示,但没有运气。
谢谢, 专利
答案 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和其他任何实现此接口的方法。