سؤال

أحاول تخزين بعض عمليات الاسترجاعات بطريقة ولكن في اشارة الى ذلك سوف أبقي الكائن المحدد على قيد الحياة، لذلك حاولت الاحتفاظ بضعف على الطريقة ولكن هذا لا يبدو أنه ممكن؟

لذا

  • لماذا لا يمكنني الاحتفاظ بمرجع ضعيف. إلى الطريقة (انظر المثال أدناه)

  • ما هي أفضل طريقة للحفاظ على طريقة المرجع؟ أي شيء في القياسية ليب؟ أو سأضطر إلى الحفاظ على الوظيفة والكائن المرجع. متفرق؟

مثال:

import weakref

class A(object):
    def m(self): pass

a = A()

import weakref

class A(object):
    def m(self): pass

a = A()

rm = weakref.ref(a.m)
print "is weak ref to method dead?",rm() is None
print "Q1. why can't i keep weakref to bound method?"

ra = weakref.ref(a)
m = a.m
print "delete object"
del a
print "is object dead?",ra() is None
print "delete method"
del m
print "is object dead?",ra() is None
print "Q2. hmmm so i am stuck i can't keep a ref as it stops the object from gc, but weakref to method isn't working?"
هل كانت مفيدة؟

المحلول

لقد طلبت نفس السؤال هنافي في سؤالي، أتحدث عن gobject، ولكن التعرف عليه مشكلة عامة في أي نوع من الثعبان! حصلت على مساعدة من قبل lioro هناك، وما أستخدمه في الرمز الحالي الخاص بي هو أدناه. بعض النقاط المهمة:

  • لا يمكنك الضعف كائن الأسلوب. يجب عليك ضعف المثال وسمة وظيفتها، أو ببساطة اسم الطريقة (كما أفعل في التعليمات البرمجية أدناه)

  • يمكنك إضافة بعض الآلية لإلغاء تسجيل رد الاتصال عندما يزول كائنك المتصل، إذا لم تقم بذلك، فسيظل لك كائن ضعيف في الإضعاف بدلا من ذلك، وطريقة فارغة عند حدوث ذلك.

.

class WeakCallback (object):
    """A Weak Callback object that will keep a reference to
    the connecting object with weakref semantics.

    This allows object A to pass a callback method to object S,
    without object S keeping A alive.
    """
    def __init__(self, mcallback):
        """Create a new Weak Callback calling the method @mcallback"""
        obj = mcallback.im_self
        attr = mcallback.im_func.__name__
        self.wref = weakref.ref(obj, self.object_deleted)
        self.callback_attr = attr
        self.token = None

    def __call__(self, *args, **kwargs):
        obj = self.wref()
        if obj:
            attr = getattr(obj, self.callback_attr)
            attr(*args, **kwargs)
        else:
            self.default_callback(*args, **kwargs)

    def default_callback(self, *args, **kwargs):
        """Called instead of callback when expired"""
        pass

    def object_deleted(self, wref):
        """Called when callback expires"""
        pass

ملاحظات الاستخدام:

# illustration how I typically use it
weak_call = WeakCallback(self._something_changed)
long_lived_object.connect("on_change", weak_call)

انا استعمل ال WeakCallback.token السمة في الفئات الفرعية التي قمت بها لإدارة قطع اتصال رد الاتصال عندما يذهب الموصل

نصائح أخرى

نظرا لأن الطريقة مرتبطة بالكائن، ماذا تتوقع أن تفعل معها إذا لم يكن الكائن موجودا؟ ماذا تحتوي على الذات؟

إذا كنت لا تحتاج إلى الكائن في الطريقة، فعليك ثم سيكون كائنك GC: D حتى إذا كان لديك مرجع طبيعي إلى الطريقة.

وصفة 6.10 في كتاب الطبخ بيثون، "الحفاظ على المراجع إلى الأساليب المحتملة دون تثبيط مجموعة القمامة"، يقدم شاملة على الرغم من مناقشة موجزة حلول. يمكنك قراءتها عبر الإنترنت (على كتب Google) هنا; ؛ نحن نقدم ائتمان لتلك الوصفة ل Knapka، Jolliton و Nicodemus (جزئيا من وصفة كتاب الطبخ الأصلي التي ذكرت بالفعل إجابة أخرى) على الرغم من بالطبع، كالعادة في كتاب الطبخ، نحن (أنا وزوجتي آنا، وديفيد أشرر) تلك المسؤولة عن التدفق الشامل للمناقشة وإصدار التعليمات البرمجية الدقيقة المختارة للطباعة، لذلك، إذا كان هناك خطأ في ذلك، فهو لنا خطأ؛-).

لديهم حل لطيف في:

http://code.activestate.com/recipes/81253/

ألق نظرة على مثال آخر، أرسلت بواسطة مجهول.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top