Как я могу определить, есть ли у подкласса Expando определенное свойство? - PullRequest
0 голосов
/ 06 января 2009

Я создаю приложение, которое я хочу иметь расширяемый набор свойств (каждое из которых является RatingProperty). Я также хочу проверить, что любые динамические свойства имеют тип RatingProperty.

В документации Expando написано:

Совет. Если вы хотите проверить значение динамического свойства с помощью класса Property, вы можете создать экземпляр класса Property и вызвать для него метод validate ().

Так что, если я хочу проверить динамическое свойство, мне нужно знать, что такое нединамические свойства класса. Как я могу спросить мой класс, каковы его определенные свойства?

Я рассмотрел вопрос о создании метода класса, который принимает строку и возвращает значение true, если эта строка находится в списке имен свойств, которые я создаю и поддерживаю, но это выглядит как хак. Я искал в Google советы, но мне не повезло.

Спасибо, Пат

Ответы [ 4 ]

1 голос
/ 02 декабря 2011

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.
1 голос
/ 07 января 2009

После еще нескольких исследований (черт возьми, лентяйка!) Я нашел решение, которое я считаю приемлемым:

Динамическое свойство не может иметь тип подкласса 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

Недостатком является то, что сохраняемое вами значение не сохраняется в качестве требуемого типа свойства.

0 голосов
/ 22 декабря 2010

Это на самом деле довольно просто!

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 и всем, что реализует этот интерфейс.

0 голосов
/ 07 января 2009

Возможно, я неправильно понимаю ваш вопрос, но если у вас есть список свойств, которые вы ожидаете найти, почему бы просто не использовать стандартную модель db.Model вместо Expando? Вы можете добавить дополнительные свойства к классу Model, если вы предоставляете значение по умолчанию или не делаете их обязательными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...