zoukankan      html  css  js  c++  java
  • 【转】实习小记-python中可哈希对象是个啥?what is hashable object in python?

    【转】实习小记-python中可哈希对象是个啥?what is hashable object in python?

      废话不多说直接祭上python3.3x的文档:(原文链接

     object.__hash__(self)

    Called by built-in function hash() and for operations on members of hashed collections including set, frozenset, and dict. __hash__() should return an integer. The only required property is that objects which compare equal have the same hash value; it is advised to somehow mix together (e.g. using exclusive or) the hash values for the components of the object that also play a part in comparison of objects.

      可哈希对象是对象拥有__hash__(self)内置函数的对象。对于可哈希的对象执行这个函数将会返回一个整数。可哈希对象判断相等的唯一条件就是两者 的哈希值相等。如果我们的对象有多个属性值,我们会使用一种方法(比方说逻辑运算异或)来将其属性值结合在一起做比较。(如果不对,麻烦一定告诉我,谢谢!)

     If a class does not define an __eq__() method it should not define a __hash__() operation either; if it defines __eq__() but not __hash__(), its instances will not be usable as items in hashable collections. If a class defines mutable objects and implements an __eq__() method, it should not implement __hash__(), since the implementation of hashable collections requires that a key’s hash value is immutable (if the object’s hash value changes, it will be in the wrong hash bucket).

      如果一个类型定义没有定义__eq__()函数,那么它也不应该定义__hash__();因为如果它定义了__eq__而没有定义__hash__,那么它的实例在某个可哈希集合中将会无效(比方说在字典/集合这类类型中)。如果一个类型定义了一个可变对象而且定义了__eq__方法,那么它不应该去定义__hash__方法,因为在哈希集合中要求其中元素的哈希值是不变的(如果某个对象实例的哈希值发生了改变,那么他将会到错误的哈希表中。。)。

    User-defined classes have __eq__() and __hash__() methods by default; with them, all objects compare unequal (except with themselves) and x.__hash__() returns an appropriate value such that x == y implies both that x is y and hash(x) == hash(y).

      用户定义的类中都有默认的__eq__和__hash__方法;有了它,所有的对象实例都是不等的(除非是自己和自己比较),在做 x == y 比较时是和这个等价的 hash(x) == hash(y)

    A class that overrides __eq__() and does not define __hash__() will have its __hash__() implicitly set to None. When the __hash__() method of a class is None, instances of the class will raise an appropriate TypeError when a program attempts to retrieve their hash value, and will also be correctly identified as unhashable when checking isinstance(obj, collections.Hashable).

      这句话的意思是,如果我们定义了一个类型,该类型只定义了__eq__而没有定义__hash__的话,那么他的__hash__()会隐式的设置为None,如果某个情况下需要这个类型的哈希值,那么程序将会报错。具体请看下面代码:

    >>> class A:
    ...     def __eq__(self, other):
    ...         return True
    ...     
    >>> a = A()
    >>> import collections
    >>> isinstance(a, collections.Hashable)  # 发现它不是可哈希对象
    False
    >>> a.__hash__
    >>> a.__hash__()
    Traceback (most recent call last):
      File "<ipython-input-20-0fddd0562e01>", line 1, in <module>
        a.__hash__()
    TypeError: 'NoneType' object is not callable

      然后往下看文档

    If a class that overrides __eq__() needs to retain the implementation of __hash__() from a parent class, the interpreter must be told this explicitly by setting __hash__ = <ParentClass>.__hash__.

      如果某个重写了__eq__方法的对象需要保留__hash__属性,那么我们需要在类型设置中添加该语句 __hash__ = <ParentClass>.__hash__

    请看代码

    >>> class A:
    ...     __hash__ = object.__hash__
    ...     def __eq__(self, other):
    ...         return True
    ...     
    >>> a = A()
    >>> a.__hash__
    <method-wrapper '__hash__' of A object at 0x7f21029cfa10>
    >>> set([a,2,3])
    {<__main__.A object at 0x7f21029cfa10>, 2, 3}

    If a class that does not override __eq__() wishes to suppress hash support, it should include __hash__ = None in the class definition. A class which defines its own __hash__() that explicitly raises a TypeError would be incorrectly identified as hashable by an isinstance(obj, collections.Hashable) call.

      如果某个类型定义需要将__hash__属性删掉,那么我们可以在类变量中这样写 __hash__ = None

      看完了还是有点小激动的,今天因为一个偶然原因,接触到了这么多的python知识。真的是相当高兴阿!

      然而我也发现__eq__ __hash__这两个方法不能随意动,如果我么需要改写其中一个的话一定要仔细考虑可能的情况,以免出现问题。

  • 相关阅读:
    log4j配置文件动态指定日志文件名称
    如何在natTable表格上添加双击事件
    如何让natTable表格支持自定义多个右键菜单
    java1.7集合源码阅读:ArrayList
    关于java1.7集合源码阅读
    多线程之:如何避免死锁
    idea控制台中文乱码“淇℃伅”
    独立的js文件中不能使用EL表达式取值
    不能在jsp页面<c:choose>对标签中使用<!---->进行注释
    Excel导入工具类
  • 原文地址:https://www.cnblogs.com/langqi250/p/10303759.html
Copyright © 2011-2022 走看看