zope.keyreference fornece referências a objetos que suportam comparação e hashes estável.
Referências-chave para Objetos Persistentes
zope.keyreference.persistent.KeyReferenceToPersistent fornece uma referência zope.keyreference.interfaces.IKeyReference para objetos persistentes.
Vejamos um exemplo. Primeiro, vamos criar alguns objetos persistentes em um banco de dados:
& Nbsp; >>> from ZODB.MappingStorage importação DB
& Nbsp; >>> transação de importação
& Nbsp; >>> from persistent.mapping PersistentMapping importação
& Nbsp; >>> db = DB ()
& Nbsp; >>> conn = db.open ()
& Nbsp; >>> root = conn.root ()
& Nbsp; >>> raiz ['ob1'] = PersistentMapping ()
& Nbsp; >>> raiz ['OB2'] = PersistentMapping ()
& Nbsp; >>> transaction.commit ()
Então vamos criar algumas referências fundamentais:
& Nbsp; >>> from zope.keyreference.persistent KeyReferenceToPersistent importação
& Nbsp; >>> key1 = KeyReferenceToPersistent (root ['ob1'])
& Nbsp; >>> key2 = KeyReferenceToPersistent (root ['OB2'])
Podemos chamar as chaves para obter os objetos:
& Nbsp; >>> key1 () é raiz ['ob1'], key2 () é raiz ['OB2']
& Nbsp; (True, True)
Novas chaves para os mesmos objetos são iguais ao velho:
& Nbsp; >>> KeyReferenceToPersistent (root ['ob1']) == key1
& Nbsp; A verdadeira
e têm os mesmos hashes:
& Nbsp; >>> de hash (KeyReferenceToPersistent (root ['ob1'])) == de hash (key1)
& Nbsp; A verdadeira
Outras implementações-chave de referência se diferem pela sua chave id tipo. Referências-chave deve classificar primeiro do seu tipo de chave e segundo em qualquer informação específica do tipo:
& Nbsp; >>> from implementos importação zope.interface
& Nbsp; >>> from zope.keyreference.interfaces importar IKeyReference
& Nbsp; >>> DummyKeyReference classe (objeto):
& Nbsp; ... implementos (IKeyReference)
& Nbsp; ... key_type_id = 'zope.app.keyreference.object'
& Nbsp; ... def __init __ (self, obj):
& Nbsp; ... self.object = obj
& Nbsp; ... def __cmp __ (self, outro):
& Nbsp; ... se self.key_type_id == other.key_type_id:
& Nbsp; ... retorno cmp (self.object, other.object)
& Nbsp; ... retorno cmp (self.key_type_id, other.key_type_id)
& Nbsp; >>> dummy_key1 = DummyKeyReference (objeto ())
& Nbsp; >>> dummy_key2 = DummyKeyReference (objeto ())
& Nbsp; >>> dummy_key3 = DummyKeyReference (objeto ())
& Nbsp; >>> chaves = [key1, dummy_key1, dummy_key2, key2, dummy_key3]
& Nbsp; >>> keys.sort ()
& Nbsp; >>> key_type_ids = [key.key_type_id para a chave em chaves]
& 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
Nós vamos armazenar as referências de chave no banco de dados:
& Nbsp; >>> raiz ['key1'] = key1
& Nbsp; >>> raiz ['key2'] = key2
e use as teclas para armazenar os objetos de novo:
& Nbsp; >>> root [key1] = raiz ['ob1']
& Nbsp; >>> root [key2] = raiz ['OB2']
& Nbsp; >>> transaction.commit ()
Agora vamos abrir outra conexão:
& Nbsp; >>> conn2 = db.open ()
E verificar se podemos usar as teclas para procurar os objetos:
& Nbsp; >>> root2 = conn2.root ()
& Nbsp; >>> key1 = root2 ['key1']
& Nbsp; >>> root2 [key1] é root2 ['ob1']
& Nbsp; A verdadeira
& Nbsp; >>> key2 = root2 ['key2']
& Nbsp; >>> root2 [key2] é root2 ['OB2']
& Nbsp; A verdadeira
e que também podemos chamar as chaves para obter os objetos:
& Nbsp; >>> key1 () é root2 ['ob1']
& Nbsp; A verdadeira
& Nbsp; >>> key2 () é root2 ['OB2']
& Nbsp; A verdadeira
Não podemos chegar a referência fundamental para um objeto que não foi salvo ainda:
& Nbsp; >>> KeyReferenceToPersistent (PersistentMapping ())
& Nbsp; ... # doctest: + ELLIPSIS
& Nbsp; Traceback (most recent call last):
& Nbsp; ...
& Nbsp; NotYet: ...
Note-se que temos um erro NotYet. Isso indica que pode ser capaz de obter uma referência chave mais tarde.
Podemos obter referências a objetos que não foram salvas se eles têm um adaptador para ZODB.interfaces.IConnection. O método add na conexão será usada para dar ao objeto um ID de objeto, que é informação suficiente para calcular a referência. Para ver isso, vamos criar um objeto que está em conformidade com IConnection de uma maneira silly:
& Nbsp; >>> import persistente
& Nbsp; >>> from ZODB.interfaces importar IConnection
& Nbsp; >>> classe C (persistent.Persistent):
& Nbsp; ... def __conform __ (self, iface):
& Nbsp; ... se iface é IConnection:
& Nbsp; ... retorno conn2
& Nbsp; >>> OB3 = C ()
& Nbsp; >>> key3 = KeyReferenceToPersistent (OB3)
& Nbsp; >>> transaction.abort ()
Resolução de Conflitos
Durante a resolução de conflitos, como discutido no ZODB / ConflictResolution.txt, referências a objetos persistentes são na verdade casos de ZODB.ConflictResolution.PersistentReference. Este é pertinente de duas maneiras para KeyReferenceToPersistent. Primeiro, ele explica a sutileza da classe: ele não herda de persistent.Persistent. Se o fizesse, não estaria disponível para a resolução de conflitos, somente o seu PersistentReference dublê.
Em segundo lugar, ele explica parte do código nos métodos __hash__ e __cmp__. Estes métodos não apenas lidar com objetos persistent.Persistent, mas objetos PersistentReference. Sem esse comportamento, objetos, como o clássico ZODB 'btrees', que usam KeyReferenceToPersistent como chaves ou membros do conjunto não será capaz de resolver os conflitos. Mesmo com o código especial, em alguns casos, a KeyReferenceToPersistent irá recusar-se a comparar e haxixe, durante a resolução de conflitos porque não pode fazê-lo de forma fiável.
__hash__ funcionará relativamente raramente durante a resolução de conflitos: somente para referências multidatabase. Aqui estão alguns exemplos.
& Nbsp; >>> from ZODB.ConflictResolution PersistentReference importação
& Nbsp; >>> def fábrica (ref):
& Nbsp; ... res = KeyReferenceToPersistent .__ novo __ (
& Nbsp; ... KeyReferenceToPersistent, ref)
& Nbsp; ... res.object = ref
& Nbsp; ... Voltar res
& Nbsp; ...
& Nbsp; >>> de hash (fábrica (PersistentReference (
& Nbsp; ... ('um OID', 'metadados class')))) # uma referência típica
& Nbsp; Traceback (most recent call last):
& Nbsp; ...
& Nbsp; ValueError: nome do banco de dados disponível no momento
& Nbsp; >>> bool (cardinal (fábrica (PersistentReference (
& Nbsp; ... ['m', ('a base de dados', 'um OID', 'metadados class')])))) # multidatabase
& Nbsp; A verdadeira
Isto significa que muitas vezes KeyReferenceToPersistent irá dificultar a resolução de conflitos de classes, como PersistentMapping.
__cmp__ funciona a menos que um objeto é uma referência multidatabase e o outro não é. Aqui estão alguns exemplos.
& Nbsp; >>> cmp (fábrica (PersistentReference (
& Nbsp; ... ('um OID', 'metadados class'))),
& Nbsp; ... fábrica (PersistentReference (
& Nbsp; ... ('um OID', 'metadados class'))))
& Nbsp; 0
& Nbsp; >>> cmp (fábrica (PersistentReference (
& Nbsp; ... ('um OID', 'metadados class'))),
& Nbsp; ... fábrica (PersistentReference (
& Nbsp; ... ('outro oid', 'metadados class'))))
& Nbsp; -1
& Nbsp; >>> cmp (fábrica (PersistentReference ('um OID')),
& Nbsp; ... fábrica (PersistentReference (
& Nbsp; ... ('um OID', 'metadados class'))))
& Nbsp; 0
& Nbsp; >>> cmp (fábrica (PersistentReference ('um OID')),
& Nbsp; ... fábrica (PersistentReference (
& Nbsp; ... ('um OID', 'metadados class'))))
& Nbsp; 0
& Nbsp; >>> cmp (fábrica (PersistentReference (
& Nbsp; ... ['m', ('a base de dados', 'um OID', 'metadados class')])),
& Nbsp; ... fábrica (PersistentReference (
& Nbsp; ... ['m', ('a base de dados', 'um OID', 'metadados class')])))
& Nbsp; 0
& Nbsp; >>> cmp (fábrica (PersistentReference (
& Nbsp; ... ['m', ('a base de dados', 'um OID', 'metadados class')])),
& Nbsp; ... fábrica (PersistentReference (
& Nbsp; ... ['n', ('a base de dados', 'um OID')])))
& Nbsp; 0
& Nbsp; >>> cmp (fábrica (PersistentReference (
& Nbsp; ... ['m', ('a base de dados', 'um OID', 'metadados class')])),
& Nbsp; ... fábrica (PersistentReference (
& Nbsp; ... ['m', ('outro banco de dados', 'um OID', 'metadados class')])))
& Nbsp; -1
& Nbsp; >>> cmp (fábrica (PersistentReference (
& Nbsp; ... ['m', ('a base de dados', 'um OID', 'metadados class')])),
& Nbsp; ... fábrica (PersistentReference (
& Nbsp; ... ('um OID', 'metadados class'))))
& Nbsp; Traceback (most recent call last):
& Nbsp; ...
& Nbsp; ValueError: Não é possível classificar de forma confiável
adaptador de ligação à base de Localização
O zope.keyreference.connectionOfPersistent função adapta objetos para conexões usando uma simples heurística baseadas em localização. É verificado se o objeto tem um __parent__ que tem uma ligação:
& Nbsp; >>> from zope.keyreference.persistent connectionOfPersistent importação
& Nbsp; >>> OB3 = PersistentMapping ()
& Nbsp; >>> print connectionOfPersistent (OB3)
& Nbsp; None
& Nbsp; >>> OB3 .__ parent__ = root2 ['ob1']
& Nbsp; >>> connectionOfPersistent (OB3) é conn2
& Nbsp; A verdadeira
O que é novo nesta versão:
- testes corrigir quebrado por remoção de zope.testing de dependências de teste: evitar o módulo ZODB3 que precisa dele.
Requisitos :
- Python
Comentários não encontrado