zope.keyreference надає посилання на об'єкти, які підтримують стійку порівняння і хеши.
Основні Посилання на постійні об'єкти
zope.keyreference.persistent.KeyReferenceToPersistent надає посилання zope.keyreference.interfaces.IKeyReference для постійних об'єктів.
Давайте подивимося на прикладі. По-перше, ми створимо деякі постійні об'єкти в базі даних:
І NBSP; >>> від ZODB.MappingStorage імпорт DB
І NBSP; >>> імпортної угоди
І NBSP; >>> від persistent.mapping імпорту PersistentMapping
І NBSP; >>> дБ = DB ()
І NBSP; >>> підключень = db.open ()
І NBSP; >>> корінь = conn.root ()
І NBSP; >>> корінь ['ob1'] = PersistentMapping ()
І NBSP; >>> корінь ['оЬ2'] = PersistentMapping ()
І NBSP; >>> transaction.commit ()
Потім ми створимо деякі ключові посилання:
І NBSP; >>> від zope.keyreference.persistent імпорту KeyReferenceToPersistent
І NBSP; >>> key1 = KeyReferenceToPersistent (корінь ['ob1'])
І NBSP; >>> key2 = KeyReferenceToPersistent (корінь ['оЬ2'])
Ми можемо назвати ключі, щоб отримати об'єкти:
І NBSP; >>> key1 () є коренем ['ob1'], key2 () є коренем ['оЬ2']
І NBSP; (True, True)
Нові ключі на ті ж об'єкти дорівнюють старий:
І NBSP; >>> KeyReferenceToPersistent (корінь ['ob1']) == key1
І NBSP; Правда
і мають ті ж хеш:
І NBSP; >>> хеш (KeyReferenceToPersistent (корінь ['ob1'])) == хеш (key1)
І NBSP; Правда
Інші основні довідкові реалізації відрізняються від їх типу ключа ID. Основні посилання повинні розібратися в першу чергу на їх тип ключа і другий на будь-яку інформацію, тіпоспеціфічной:
І NBSP; >>> від zope.interface знарядь імпортних
І NBSP; >>> від zope.keyreference.interfaces імпортувати IKeyReference
І NBSP; >>> класу DummyKeyReference (об'єкт):
І NBSP; ... інвентар (IKeyReference)
І NBSP; ... key_type_id = 'zope.app.keyreference.object "
І NBSP; ... Def __init __ (сам, об'єкт):
І NBSP; ... self.object = OBJ
І NBSP; ... Def __cmp __ (сам, інше):
І NBSP; ... якщо self.key_type_id == other.key_type_id:
І NBSP; ... повернення CMP (self.object, other.object)
І NBSP; ... повернення CMP (self.key_type_id, other.key_type_id)
І NBSP; >>> dummy_key1 = DummyKeyReference (об'єкт ())
І NBSP; >>> dummy_key2 = DummyKeyReference (об'єкт ())
І NBSP; >>> dummy_key3 = DummyKeyReference (об'єкт ())
І NBSP; >>> клавіші = [key1, dummy_key1, dummy_key2, key2, dummy_key3]
І NBSP; >>> keys.sort ()
І NBSP; >>> key_type_ids = [key.key_type_id для ключа в ключах]
І NBSP; >>> key_type_ids [0: 3] .count ('zope.app.keyreference.object')
І NBSP; 3
. & NBSP; >>> key_type_ids [3:] COUNT ('zope.app.keyreference.persistent')
І NBSP; 2
Ми зберігайте ключ посилання в базі даних:
І NBSP; >>> корінь ['key1'] = key1
І NBSP; >>> корінь ['key2'] = key2
і використовувати клавіші для збереження об'єктів знову:
& NBSP; >>> корінь [key1] = корінь ['ob1']
& NBSP; >>> корінь [key2] = корінь ['оЬ2']
І NBSP; >>> transaction.commit ()
Тепер ми відкриємо ще один виклик:
І NBSP; >>> conn2 = db.open ()
І переконайтеся, що ми можемо використовувати ключі перегляду об'єктів:
І NBSP; >>> root2 = conn2.root ()
І NBSP; >>> key1 = root2 ['key1']
І NBSP; >>> root2 [key1] є root2 ['ob1']
І NBSP; Правда
І NBSP; >>> key2 = root2 ['key2']
І NBSP; >>> root2 [key2] є root2 ['оЬ2']
І NBSP; Правда
і що ми можемо називати також ключі, щоб отримати об'єкти:
І NBSP; >>> key1 () є root2 ['ob1']
І NBSP; Правда
І NBSP; >>> key2 () є root2 ['оЬ2']
І NBSP; Правда
Ми не можемо отримати ключ посилання на об'єкт, який не був збережений ще:
І NBSP; >>> KeyReferenceToPersistent (PersistentMapping ())
І NBSP; ... # doctest: + Многоточие
І NBSP; Traceback (останній виклик останнього):
І NBSP; ...
І NBSP; NotYet: ...
Зверніть увагу, що ми отримуємо помилку NotYet. Це означає, що ми могли б отримати ключовий посилання нижче.
Ми можемо отримати посилання на незбережених об'єктів, якщо вони є адаптер для ZODB.interfaces.IConnection. Додати метод на зв'язку буде використовуватися для отримання цільового ідентифікатор об'єкта, який є достатньо інформації, щоб обчислити посилання. Щоб переконатися в цьому, ми створимо об'єкт, який відповідає IConnection в нерозумно:
І NBSP; >>> імпорту стійкі
І NBSP; >>> від ZODB.interfaces імпортувати IConnection
І NBSP; >>> класу C (persistent.Persistent):
І NBSP; ... Def __conform __ (сам, IFACE):
І NBSP; ... якщо IFACE є IConnection:
І NBSP; ... повернення conn2
І NBSP; >>> OB3 = C ()
І NBSP; >>> ключ3 = KeyReferenceToPersistent (OB3)
І NBSP; >>> transaction.abort ()
Вирішення конфліктів
Під час вирішення конфліктів, як це описано в ZODB / ConflictResolution.txt, посилання на постійних об'єктів, насправді випадки ZODB.ConflictResolution.PersistentReference. Це доречно в двох напрямках для KeyReferenceToPersistent. По-перше, це пояснює тонкощі класу: він не успадковує від persistent.Persistent. Якщо це так, то не було б доступно для вирішення конфліктів, тільки його PersistentReference стояти в.
По-друге, це пояснює деякі з коду в __hash__ і __cmp__ методів. Ці методи не тільки обробляти об'єкти persistent.Persistent, але об'єкти PersistentReference. Без цього поведінки, об'єкти, такі як класичний ZODB BTrees, які використовують KeyReferenceToPersistent в якості ключів або встановити членів не зможе вирішувати конфлікти. Навіть зі спеціальним кодом, в деяких випадках KeyReferenceToPersistent відмовиться порівняти і хеш при вирішенні конфліктів, тому що він не може надійно робити.
__hash__ буде працювати порівняно рідко при вирішенні конфліктів: тільки посилання мультібаз. Ось кілька прикладів.
І NBSP; >>> від ZODB.ConflictResolution імпорту PersistentReference
І NBSP; >>> Def завод (посилання):
І NBSP; ... дозволом = KeyReferenceToPersistent .__ новий __ (
І NBSP; ... KeyReferenceToPersistent, посилання)
І NBSP; ... res.object = посилання
І NBSP; ... повернення дозволом
І NBSP; ...
І NBSP; >>> хеш (заводська (PersistentReference (
& NBSP; ... ('OID', 'класу метадані')))) # типовий посилання
І NBSP; Traceback (останній виклик останнього):
І NBSP; ...
І NBSP; ValueError: ім'я бази даних недоступний, в даний момент
І NBSP; >>> BOOL (хеш (заводська (PersistentReference (
& NBSP; ... ['M', ("база даних", "OID", "клас метаданих ')])))) # мультібаз
І NBSP; Правда
Це означає, що KeyReferenceToPersistent часто заважають вирішенню конфліктів для класів, таких як PersistentMapping.
__cmp__ працює, якщо один об'єкт не мультібаз довідково-другий немає. Ось кілька прикладів.
І NBSP; >>> CMP (завод (PersistentReference (
І NBSP; ... ('під'язикова', 'клас метаданих "))),
І NBSP; ... завод (PersistentReference (
& NBSP; ... ('OID', 'класу метадані'))))
І NBSP; 0
І NBSP; >>> CMP (завод (PersistentReference (
І NBSP; ... ('під'язикова', 'клас метаданих "))),
І NBSP; ... завод (PersistentReference (
& NBSP; ... ("інший OID ',' класу метадані '))))
І NBSP; -1
І NBSP; >>> CMP (завод (PersistentReference ('під'язикова')),
І NBSP; ... завод (PersistentReference (
& NBSP; ... ('OID', 'класу метадані'))))
І NBSP; 0
І NBSP; >>> CMP (завод (PersistentReference ('під'язикова')),
І NBSP; ... завод (PersistentReference (
& NBSP; ... ('OID', 'класу метадані'))))
І NBSP; 0
І NBSP; >>> CMP (завод (PersistentReference (
І NBSP; ... ['м', ('бази даних', 'під'язикова', 'метаданих класу')])),
І NBSP; ... завод (PersistentReference (
І NBSP; ... ['м', ('бази даних', 'під'язикова', 'клас метаданих')])))
І NBSP; 0
І NBSP; >>> CMP (завод (PersistentReference (
І NBSP; ... ['м', ('бази даних', 'під'язикова', 'метаданих класу')])),
І NBSP; ... завод (PersistentReference (
І NBSP; ... ['N', ('бази даних', 'під'язикова')])))
І NBSP; 0
І NBSP; >>> CMP (завод (PersistentReference (
І NBSP; ... ['м', ('бази даних', 'під'язикова', 'метаданих класу')])),
І NBSP; ... завод (PersistentReference (
І NBSP; ... ['м', ('іншої бази даних', 'під'язикова', 'клас метаданих')])))
І NBSP; -1
І NBSP; >>> CMP (завод (PersistentReference (
І NBSP; ... ['м', ('бази даних', 'під'язикова', 'метаданих класу')])),
І NBSP; ... завод (PersistentReference (
& NBSP; ... ('OID', 'класу метадані'))))
І NBSP; Traceback (останній виклик останнього):
І NBSP; ...
І NBSP; ValueError: не можемо сортувати надійно
на основі місця розташування Адаптер підключення
Функція zope.keyreference.connectionOfPersistent адаптується об'єктів у зв'язку з використанням простого на основі визначення місця розташування евристичний аналізатор. Це перевіряється на об'єкт має __parent__, яка має зв'язок:
І NBSP; >>> від zope.keyreference.persistent імпорту connectionOfPersistent
І NBSP; >>> OB3 = PersistentMapping ()
І NBSP; >>> друку connectionOfPersistent (OB3)
НЕ & NBSP; Ні
І NBSP; >>> OB3 .__ parent__ = root2 ['ob1']
І NBSP; >>> connectionOfPersistent (OB3) є conn2
І NBSP; True
Що нового У цьому випуску:
- Fix тести розбиті видалення zope.testing від залежностей між тестами: уникнути ZODB3 модуль, який її потребує.
Вимоги
- Python
Коментар не знайдено