Как получить все свойства класса (в Python) полимодели GAE, в том числе определенные через @property
Я использую полимодель Google App Engine для моделирования данных, которые могут иметь более одного экземпляра свойства - например, у контакта может быть несколько телефонных номеров. Скажи, что это моя установка:
class Foo(polymodel.PolyModel):
some_prop = ndb.StringProperty()
@property
def bar(self):
return Bar.query(Bar.foo == self.key)
class Bar(ndb.Model):
foo = ndb.KeyProperty(kind = Foo)
other_prop= ndb.StringProperty()
(Я получил этот подход после прочтения этой статьи GAE по моделированию данных: https://developers.google.com/appengine/articles/modeling)
Теперь, когда я делаю:
Foo._properties
Я получаю доступ только к следующему:
{'some_prop': StringProperty('some_prop'),
'class': _ClassKeyProperty('class', repeated=True)}
Есть ли способ получить доступ ко ВСЕМ свойствам, в том числе определенным с помощью @property?
Большое спасибо за любую помощь или понимание того, где я иду не так. - Ли
ОБНОВЛЕНИЕ: Основываясь на отличном ответе @FastTurle, я теперь добавил метод класса, который возвращает оба свойства класса, а также методы, помеченные как свойства через @property:
def props(self):
return dict(self._properties.items() + \
{attr_name:getattr(self,attr_name) for \
attr_name, attr_value in \
Foo.__dict__.iteritems() if \
isinstance(attr_value,property)}.items())
1 ответ
Выполнение Foo._properties
должен получить доступ к любым атрибутам, которые вы определяете на своем polymodel.PolyModel
которые наследуют от google.appengine.ext.db.Property
,
Это означает, что KeyProperty
, StringProperty
и т.д... появится в Foo._properties
так что я предполагаю, что теперь вам нужно найти все методы, украшенные property
,
К счастью, это не так сложно. Во-первых, быстрый уклон в декораторы (простите, если вы уже знаете это).
В питоне декораторы являются просто синтаксическим сахаром. Например, эти два метода приводят к одному и тому же:
@property
def bar(self):
pass
def bar(self):
pass
bar = property(bar)
К счастью для нас, property(obj)
возвращает новый property
объект. Это также означает, что @property
возвращает property
объект также. Вы можете думать о property
как класс! И, наконец, можно использовать isinstance(bar, property)
увидеть, если bar
это собственность.
Наконец, мы можем использовать это, изучив каждый из Foo
атрибуты и выбирая только те, которые property
экземпляров.
for attr_name, attr_value in Foo.__dict__.iteritems():
if isinstance(attr_value, property):
print attr_name, attr_value
# bar, <property object at ...>