سؤال

كان غريب الخلل عند ترقية ميزة الثعبان 3.1 شوكة من البرنامج.لقد ضيقت على الفرضية التالية:

وعلى النقيض من بيثون 2.x في بيثون 3.× إذا كان كائن يحتوي على __eq__ الأسلوب هو تلقائيا unhashable.

هل هذا صحيح ؟

هنا ما يحدث في بيثون 3.1:

>>> class O(object):
...     def __eq__(self, other):
...         return 'whatever'
...
>>> o = O()
>>> d = {o: 0}
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    d = {o: 0}
TypeError: unhashable type: 'O'

متابعة السؤال هو كيف يمكنني حل رأيي الشخصي المشكلة ؟ أنا كائن ChangeTracker الذي يخزن WeakKeyDictionary الذي يشير إلى عدة كائنات ، مما يتيح لكل قيمة المخلل تفريغ عند نقطة زمنية معينة في الماضي.كلما كائن موجود هو مؤكد في التغيير تعقب يقول إذا الجديدة المخلل هو نفس القديم, ولذلك أقول ما إذا كان الكائن قد تغير في الوقت الحالي.المشكلة الآن لا أستطيع حتى تحقق ما إذا كان كائن معين في المكتبة ، لأنه يجعل من رفع استثناء عن الكائن الذي unhashable.(لأنه لديه __eq__ الأسلوب.) كيف يمكن التغلب على هذه المشكلة ؟

هل كانت مفيدة؟

المحلول

نعم، إذا قمت بتعريف __eq__، و__hash__ الافتراضي (أي تجزئة عنوان الكائن في الذاكرة) يذهب بعيدا. هذا أمر مهم لأن التجزئة تحتاج إلى أن تكون متسقة مع المساواة: المساواة في الأشياء تحتاج إلى تجزئة نفسه

والحل بسيط: فقط تحديد __hash__ جنبا إلى جنب مع تحديد __eq__

نصائح أخرى

هذه الفقرة من http://docs.python.org/3.1/reference/datamodel.html#object.تجزئة

إذا كانت الفئة التي يتجاوز __eq__() تحتاج إلى الاحتفاظ تنفيذ __hash__() من فئة الأم, يجب أن يكون المترجم قال هذا صراحة من خلال وضع __hash__ = <ParentClass>.__hash__.وإلا الميراث __hash__() سوف يكون منعت ، __hash__ كان صراحة لا شيء.

التحقق من بيثون 3 دليل object.__hash__:

إذا فئة لا تعريف __eq__() الأسلوب يجب أن لا تحدد __hash__() العملية سواء ؛ إذا كان يعرف __eq__() ولكن ليس __hash__(), ، في الحالات التي لا يمكن استخدامها كعناصر في hashable مجموعات.

التركيز هو الألغام.

إذا كنت تريد أن تكون كسول ، يبدو مثل يمكنك فقط تحديد __hash__(self) العودة id(self):

المعرفة من قبل المستخدم الطبقات __eq__() و __hash__() أساليب افتراضيا ؛ مع كل الكائنات مقارنة غير متكافئة (إلا أنفسهم) ، x.__hash__() يعود id(x).

وأنا لست خبيرا الثعبان، ولكن لن يكون من المنطقي أنه عند تحديد مكافئ، طريقة، لديك أيضا لتحديد تجزئة-طريقة وكذلك (الذي يحسب قيمة التجزئة لكائن) وإلا، ان آلية التجزئة لا نعرف ما اذا كان ضرب نفس الكائن، أو كائن آخر فقط مع نفس القيمة التجزئة. في الواقع، انها على العكس من ذلك، فإنه على الأرجح في نهاية المطاف الحوسبة قيم التجزئة المختلفة للكائنات تعتبر متساوية بطريقة __eq__ الخاص بك.

وليس لدي أي فكرة عما يسمى ذلك ظيفة تجزئة على الرغم من __hash__ ربما؟ :)

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