-
Notifications
You must be signed in to change notification settings - Fork 0
Интерфейс
Далее используются примеры из онтологии
Использование пространств имен
Получение подклассов для класса
Воссоздание иерархии наследования классов
Получение свойств объекта, итерация по свойствам
Создание нового объекта класса
Чтобы каждый раз не прописывать длинный префикс к каждому свойству, можно использовать пространства имен:
from rdflib import Namespace
db = AllegroBackend(<route to triplestore>)
c = Connection(db)
factory = Factory(c)
# хештег в конце ссылки на пространство обязателен
local = Namespace("http://www.owl-ontologies.com/Ontology1359802755.owl#")
cl = factory.get_class(local.User)
print local.User
print cl.uri
http://www.owl-ontologies.com/Ontology1359802755.owl#User
http://www.owl-ontologies.com/Ontology1359802755.owl#User
Далее в примерах кода будет предполагаться, что factory и пространство имен local уже созданы
Класс можно получить по полному URI или сокращенному.
cl1 = factory.get_class(local.User)
cl2 = factory.get_class("http://www.owl-ontologies.com/Ontology1359802755.owl#User")
print "short URI", cl1.uri
print "full URI", cl2.uri
print "are they equal?", cl1 == cl2
short URI http://www.owl-ontologies.com/Ontology1359802755.owl#User
full URI http://www.owl-ontologies.com/Ontology1359802755.owl#User
are they equal? True
cls = factory.get_class(local.SectionElement)
print cls.get_subclasses()
[class TermDefinition, class Article, class Post, class Term]
Все экземпляры класса будут типизированы классом из онтологии. То есть, если искать объекты класса http://www.owl-ontologies.com/Ontology1359802755.owl#User
, то получим список объектов типа User
с URI, соответствущими искомым объектам из онтологии
users = factory.get_class(local.User)
for x in users.get_objects():
print "%s, %s" % (type(x), x)
class User, object Elena
class User, object Emma
class User, object Sarah
Объект можно получить по полному URI или сокращенному
obj = factory.get_object(local.Sarah)
obj2 = factory.get_object("http://www.owl-ontologies.com/Ontology1359802755.owl#Sarah")
print obj.uri
print obj2.uri
print "are they equal?", obj == obj2
u'http://www.owl-ontologies.com/Ontology1359802755.owl#Sarah'
u'http://www.owl-ontologies.com/Ontology1359802755.owl#Sarah'
are they equal? True
Каждый раз, когда возвращается класс через получение класса или объекта, вместе в ним из онтологии забирается и вся его иерархия наследования. Это сделано как для того, чтобы максимально полно отобразить модель в программном коде, так и по техническим причинам (более простой алгоритм получения свойств).
cl = factory.get_class(local.Article)
print cl
pprint(cl.__mro__)
obj = factory.get_object(local.ArticleAboutAuthor)
print obj
pprint(obj.__class__.__mro__)
class Article
(class Article,
class SectionElement,
<class 'one.SemanticObjects.SemanticObjects.Thing'>,
<type 'object'>)
object ArticleAboutAuthor
(class Article,
class SectionElement,
<class 'one.SemanticObjects.SemanticObjects.Thing'>,
<type 'object'>)
Все свойства для объекта или класса доступны в виде обычных атрибутов Python.
cl = factory.get_class(local.Article)
print cl
pprint(dir(cl))
obj = factory.get_object(local.ArticleAboutAuthor)
print obj
pprint(dir(obj))
class Article
['__class__',
'__delattr__',
'__dict__',
'__doc__',
'__format__',
'__getattribute__',
'__hash__',
'__init__',
'__module__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'factory',
'filter',
'get_objects',
'get_subclasses',
'http://www.owl-ontologies.com/Ontology1359802755.owl#belongsToSection',
'http://www.owl-ontologies.com/Ontology1359802755.owl#hasImage',
'http://www.owl-ontologies.com/Ontology1359802755.owl#hasSectionElementContent',
'http://www.owl-ontologies.com/Ontology1359802755.owl#hasTxtContent',
'http://www.owl-ontologies.com/Ontology1359802755.owl#precedes',
'uri']
object ArticleAboutAuthor
['__class__',
'__delattr__',
'__dict__',
'__doc__',
'__format__',
'__getattribute__',
'__hash__',
'__init__',
'__module__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__weakref__',
'factory',
'filter',
'get_objects',
'get_subclasses',
'http://www.owl-ontologies.com/Ontology1359802755.owl#belongsToSection',
'http://www.owl-ontologies.com/Ontology1359802755.owl#hasImage',
'http://www.owl-ontologies.com/Ontology1359802755.owl#hasSectionElementContent',
'http://www.owl-ontologies.com/Ontology1359802755.owl#hasTxtArticleContent',
'http://www.owl-ontologies.com/Ontology1359802755.owl#hasTxtContent',
'http://www.owl-ontologies.com/Ontology1359802755.owl#precedes',
'http://www.w3.org/2000/01/rdf-schema#label',
'uri']
Легко можно заметить, что часть свойств определена в классе, а часть - в объекте.
cl = factory.get_class(local.Article)
obj = factory.get_object(local.ArticleAboutAuthor)
pprint(set(dir(obj))-set(dir(cl)))
set(['http://www.owl-ontologies.com/Ontology1359802755.owl#hasTxtArticleContent',
'http://www.w3.org/2000/01/rdf-schema#label'])
Все свойства типизированы. Для классов свойства это соответствующие классы Python, для объектов - объекты этих классов.
obj = factory.get_object(local.ArticleAboutAuthor)
pprint([(x, type(getattr(obj, x)[0]), getattr(obj, x)) for x in obj.__dict__])
[('http://www.owl-ontologies.com/Ontology1359802755.owl#hasTxtArticleContent',
<type 'unicode'>,
[u'It is very short article about J. K. Rowling.']),
('http://www.owl-ontologies.com/Ontology1359802755.owl#hasSectionElementContent',
<class 'rdflib.term.Literal'>,
[rdflib.term.Literal(u'British novelist, best known as the author of the Harry Potter fantasy series. The Potter books have gained worldwide attention, won multiple awards, and sold more than 400 million copies. They have become the best-selling book series in history, and been the basis for a series of films which has become the highest-grossing film series in history. Rowling had overall approval on the scripts as well as maintaining creative control by serving as a producer on the final instalment.', lang=u'en')]),
('http://www.w3.org/2000/01/rdf-schema#label',
<class 'rdflib.term.Literal'>,
Label(en=rdflib.term.Literal(u'Article about Author', lang=u'en'))),
('uri',
<type 'unicode'>,
u'http://www.owl-ontologies.com/Ontology1359802755.owl#ArticleAboutAuthor'),
('http://www.owl-ontologies.com/Ontology1359802755.owl#belongsToSection',
class Section,
[object Author])]
obj = factory.get_class(local.Section)
pprint([(x, getattr(obj, x)) for x in obj.__dict__])
[('factory',
<one.SemanticObjects.SemanticObjects.Factory object at 0x7ff30019ce50>),
('__module__', 'one.SemanticObjects.SemanticObjects'),
('http://www.owl-ontologies.com/Ontology1359802755.owl#hasTxtContent',
class string),
('http://www.owl-ontologies.com/Ontology1359802755.owl#subSectionOf',
class Section),
('uri',
rdflib.term.URIRef(u'http://www.owl-ontologies.com/Ontology1359802755.owl#Section')),
('http://www.owl-ontologies.com/Ontology1359802755.owl#hasSectionElement',
class SectionElement),
('__doc__', None)]
Языковые литералы отображаются в именованный кортеж, ключами которого являются языки.
obj = factory.get_object(local.Author)
pprint([(x, getattr(obj, x)) for x in obj.__dict__])
[('http://www.owl-ontologies.com/Ontology1359802755.owl#hasSectionElement',
[object PostFilmRights, object ArticleAboutAuthor]),
('http://www.w3.org/2000/01/rdf-schema#label',
Label(ru=rdflib.term.Literal(u'\u0410\u0432\u0442\u043e\u0440', lang=u'ru'), en=rdflib.term.Literal(u'Author', lang=u'en'))),
('uri', u'http://www.owl-ontologies.com/Ontology1359802755.owl#Author'),
('http://www.owl-ontologies.com/Ontology1359802755.owl#subSectionOf',
[object HarryPotter])]
При этом сохраняется возможность итерации по ним, как по остальным свойствам.
bj = factory.get_object(local.Author)
pprint(obj.__dict__)
for key, values in obj.__dict__.items():
for value in values:
print "%s that %s" % (key, value)
http://www.owl-ontologies.com/Ontology1359802755.owl#hasSectionElement that object PostFilmRights
http://www.owl-ontologies.com/Ontology1359802755.owl#hasSectionElement that object ArticleAboutAuthor
http://www.w3.org/2000/01/rdf-schema#label that Автор
http://www.w3.org/2000/01/rdf-schema#label that Author
Работают стандартные способы проверки принадлежности атрибута классу или объекту.
obj = factory.get_object(local.Author)
print "hasattr?", hasattr(obj, RDFS.label)
print "getattr:", getattr(obj, RDFS.label).ru
print "getattr:", getattr(obj, RDFS.label)
hasattr? True
getattr: Автор
getattr: Label(ru=rdflib.term.Literal(u'\u0410\u0432\u0442\u043e\u0440', lang=u'ru'), en=rdflib.term.Literal(u'Author', lang=u'en'))
В онтологии уже существует класс, необходимо получить экземпляры класса c определенным значением свойства
Передача условий фильтрации идет через именованные аргументы. Для удобства можно передавать словарь без предварительной распаковки.
kwargs = {local.knows: local.Sarah, local.adds: local.ElenaWorkspace}
print factory.get_class(local.User).filter(**kwargs)
print factory.get_class(local.User).filter(kwargs)
[object Elena]
[object Elena]
Если factory передать uri, которого нет в онтологии - будет создан новый класс. Отдельного метода для сохранения нет! Сохранение идет в момент вызова get_class
cls = factory.get_class(local.SectionElement1)
В результате выполнения в онтологии появится запись вида:
http://www.owl-ontologies.com/Ontology1359802755.owl#SectionElement1 a rdfs:Class
Для этого применяется схема, стандартная для Django: получается класс и через его инстанцирование создается объект.
cls = factory.get_class(local.SectionElement)
new_section = cls(local.NewSectionElement)
В результате выполнения в онтологии появится запись вида:
http://www.owl-ontologies.com/Ontology1359802755.owl#NewSectionElement a http://www.owl-ontologies.com/Ontology1359802755.owl#SectionElement