zope.keyreference מספק אזכור אובייקט התומכים בהשוואה וגיבובים יציבים.
הערות מפרט אובייקטי Persistent
zope.keyreference.persistent.KeyReferenceToPersistent מספק התייחסות zope.keyreference.interfaces.IKeyReference לאובייקטים מתמשכים.
בואו נסתכל על דוגמא. ראשית, אנו ניצור כמה חפצים מתמשכים בבסיס נתונים:
& Nbsp; >>> מZODB.MappingStorage יבוא DB
& Nbsp; >>> עסקת יבוא
& Nbsp; >>> מPersistentMapping יבוא persistent.mapping
& Nbsp; >>> db = DB ()
& Nbsp; >>> conn = db.open ()
& Nbsp; >>> שורש = conn.root ()
& Nbsp; >>> שורש ['ob1'] = PersistentMapping ()
& Nbsp; >>> שורש ['ob2'] = PersistentMapping ()
& Nbsp; >>> transaction.commit ()
אז ליצור כמה אזכור מפתח:
& Nbsp; >>> מKeyReferenceToPersistent יבוא zope.keyreference.persistent
& Nbsp; >>> key1 = KeyReferenceToPersistent (שורש ['ob1'])
& Nbsp; >>> key2 = KeyReferenceToPersistent (שורש ['ob2'])
אנו יכולים לקרוא את המפתחות כדי לקבל את החפצים:
& Nbsp; >>> key1 () הוא שורש ['ob1'], key2 () הוא שורש ['ob2']
& Nbsp; (נכון, נכון)
מפתחות חדשים לאותם אובייקטים שווים לישן:
& 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 __ (עצמי, obj):
& 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:] לספור ('zope.app.keyreference.persistent')
& Nbsp; 2
אנחנו לאחסן אזכור מפתח באתר:
& Nbsp; >>> שורש ['key1'] = key1
& Nbsp; >>> שורש ['key2'] = key2
והשתמש במקשים כדי לאחסן את החפצים שוב:
& Nbsp; >>> שורש [key1] = שורש ['ob1']
& Nbsp; >>> שורש [key2] = שורש ['ob2']
& 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 ['ob2']
& Nbsp; נכון
ושאנחנו יכולים גם לקרוא את המפתחות כדי לקבל את החפצים:
& Nbsp; >>> key1 () הוא root2 ['ob1']
& Nbsp; נכון
& Nbsp; >>> key2 () הוא root2 ['ob2']
& Nbsp; נכון
אנחנו לא יכולים לקבל את ההתייחסות המרכזית לאובייקט שלא נשמר עדיין:
& Nbsp; >>> KeyReferenceToPersistent (PersistentMapping ())
& Nbsp; ... # doctest: + שלוש נקודות
& Nbsp; Traceback (השיחה האחרונה שעברה):
& Nbsp; ...
& Nbsp; NotYet: ...
שים לב שאנחנו מקבלים שגיאת NotYet. זה מצביע על כך שאולי תוכל לקבל התייחסות מפתח מאוחר יותר.
אנחנו יכולים לקבל אזכור של אובייקטים שלא נשמרו אם יש להם מתאם לZODB.interfaces.IConnection. שיטת התוספת על החיבור תשמש לתת האובייקט id אובייקט, שהוא מספיק מידע כדי לחשב את ההתייחסות. כדי לראות זאת, ניצור אובייקט שעומד בIConnection באופן טיפשי:
& Nbsp; >>> יבוא מתמשך
& Nbsp; >>> מZODB.interfaces לייבא IConnection
& Nbsp; >>> C כיתה (persistent.Persistent):
& Nbsp; ... def __conform __ (עצמי, iface):
& Nbsp; ... אם iface הוא IConnection:
& Nbsp; ... conn2 תמורה
& Nbsp; >>> ob3 = C ()
& Nbsp; >>> key3 = 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__ יעבוד רק לעתים נדירות יחסית בפתרון סכסוכים: רק לאזכור multidatabase. הנה כמה דוגמאות.
& Nbsp; >>> מPersistentReference יבוא ZODB.ConflictResolution
& Nbsp; >>> מפעל def (נ"צ):
& Nbsp; ... מיל = KeyReferenceToPersistent .__ חדש __ (
& Nbsp; ... KeyReferenceToPersistent, נ"צ)
& Nbsp; ... res.object = נ"צ
& Nbsp; ... מיל תמורה
& Nbsp; ...
& Nbsp; >>> חשיש (מפעל (PersistentReference (
& Nbsp; ... (, 'מטה כיתה' 'OID')))) # התייחסות טיפוסית
& Nbsp; Traceback (השיחה האחרונה שעברה):
& Nbsp; ...
& Nbsp; ValueError: שם מסד הנתונים אינו זמין בשלב זה
& Nbsp; >>> bool (hash (מפעל (PersistentReference (
& Nbsp; ... ['מ' ', (' מסד נתונים ',' OID ',' מטה כיתה ')])))) # multidatabase
& Nbsp; נכון
משמעות הדבר היא כי KeyReferenceToPersistent לעתים קרובות לעכב פתרון סכסוכים לכיתות כגון PersistentMapping.
__cmp__ עובד, אלא אם כן אובייקט אחד הוא התייחסות multidatabase והשני הוא לא. הנה כמה דוגמאות.
& Nbsp; >>> CMP (מפעל (PersistentReference (
& Nbsp; ... ('OID', 'מטה כיתה "))),
& Nbsp; ... מפעל (PersistentReference (
& Nbsp; ... ('OID', 'מטה כיתה "))))
& Nbsp; 0
& Nbsp; >>> CMP (מפעל (PersistentReference (
& Nbsp; ... ('OID', 'מטה כיתה "))),
& Nbsp; ... מפעל (PersistentReference (
& Nbsp; ... ('אחר OID', 'מטה כיתה "))))
& Nbsp; -1
& Nbsp; >>> CMP (מפעל (PersistentReference ('OID')),
& Nbsp; ... מפעל (PersistentReference (
& Nbsp; ... ('OID', 'מטה כיתה "))))
& Nbsp; 0
& Nbsp; >>> CMP (מפעל (PersistentReference ('OID')),
& Nbsp; ... מפעל (PersistentReference (
& Nbsp; ... ('OID', 'מטה כיתה "))))
& Nbsp; 0
& Nbsp; >>> CMP (מפעל (PersistentReference (
& Nbsp; ... ['מ' ', (' מסד נתונים ',' OID ',' מטה כיתה ')])),
& Nbsp; ... מפעל (PersistentReference (
& Nbsp; ... ['מ' ', (' מסד נתונים ',' OID ',' מטה כיתה ')])))
& Nbsp; 0
& Nbsp; >>> CMP (מפעל (PersistentReference (
& Nbsp; ... ['מ' ', (' מסד נתונים ',' OID ',' מטה כיתה ')])),
& Nbsp; ... מפעל (PersistentReference (
& Nbsp; ... ['n', ('מסד נתונים', 'OID')])))
& Nbsp; 0
& Nbsp; >>> CMP (מפעל (PersistentReference (
& Nbsp; ... ['מ' ', (' מסד נתונים ',' OID ',' מטה כיתה ')])),
& Nbsp; ... מפעל (PersistentReference (
& Nbsp; ... ['מ' ', (' מסד נתונים אחר ',' OID ',' מטה כיתה ')])))
& Nbsp; -1
& Nbsp; >>> CMP (מפעל (PersistentReference (
& Nbsp; ... ['מ' ', (' מסד נתונים ',' OID ',' מטה כיתה ')])),
& Nbsp; ... מפעל (PersistentReference (
& Nbsp; ... ('OID', 'מטה כיתה "))))
& Nbsp; Traceback (השיחה האחרונה שעברה):
& Nbsp; ...
& Nbsp; ValueError: לא ניתן למיין באופן מהימן
מתאם חיבור מבוסס מיקום
Zope.keyreference.connectionOfPersistent הפונקציה מתאים את עצמו לאובייקטי חיבורים באמצעות היוריסטי מבוסס מיקום פשוט. זה בדק אם האובייקט יש __parent__ שיש לו קשר:
& Nbsp; >>> מconnectionOfPersistent יבוא zope.keyreference.persistent
& Nbsp; >>> ob3 = PersistentMapping ()
& Nbsp; >>> connectionOfPersistent הדפסה (ob3)
& Nbsp; אין
& Nbsp; >>> ob3 .__ parent__ = root2 ['ob1']
& Nbsp; >>> connectionOfPersistent הוא (ob3) conn2
& Nbsp; נכון
מה חדש בהודעה זו:
- בדיקות תקן נשבר על ידי הסרת zope.testing מתלות בדיקה: להימנע מודול ZODB3 שזקוק לו.
דרישות :
- Python
תגובות לא נמצא