• Pthon魔术方法(Magic Methods)-hash


                  Pthon魔术方法(Magic Methods)-hash

                                          作者:尹正杰

    版权声明:原创作品,谢绝转载!否则将追究法律责任。

    一.hash方法

    __hash__:
      内建函数hash()调用的返回值,返回一个整数。如果定义这个方法该类的实例就可hash。

    __eq__:
      对应"=="操作符,判断两个对象内容是否相等,返回bool值。
      定义了这个方法,如果不提供"__hash__"方法,那么实例将不可hash了。
      "__hash__"方法只是返回一个hash值作为set的key,但是去重还需要"__eq__"来判断两个对象是否相等。
      hash值相同,只是hash冲突,不能说明两个对象是相等的。因此一半来说提供"__hash__"方法是为了作为set或者dict的key,如果去重同时要提供"__eq__"方法。
     
    温馨提示:
      不可hash对象isinstance(p1,collections.Hashable)一定为False。
      去重需要提供"__eq__"方法。

    二.案例展示

     1 #!/usr/bin/env python
     2 #_*_conding:utf-8_*_
     3 #@author :yinzhengjie
     4 #blog:http://www.cnblogs.com/yinzhengjie
     5 
     6 """
     7     设计二维坐标类Point,使其成为可hash类型,并比较2个坐标的实例是否相等。
     8 """
     9 
    10 from collections import Hashable
    11 
    12 class Point:
    13     def __init__(self,x,y):
    14         self.x = x
    15         self.y = y
    16 
    17     def __hash__(self):
    18         return hash((self.x,self.y))
    19 
    20     def __eq__(self, other):
    21         if self is other:
    22             return True
    23         else:
    24             return self.x == other.x and self.y == other.y
    25 
    26     def __repr__(self):
    27         return "{}:{}".format(self.x,self.y)
    28 
    29 p1 = Point(10,20)
    30 p2 = Point(10,20)
    31 
    32 print(hash(p1))
    33 print(hash(p2))
    34 
    35 print(p1 is p2)
    36 print(p1 == p2)
    37 print(hex(id(p1)),hex(id(p2)))
    38 print(set((p1,p2)))
    39 print(isinstance(p1,Hashable))
    40 
    41 
    42 
    43 #以上代码执行结果如下:
    44 3713074054217192181
    45 3713074054217192181
    46 False
    47 True
    48 0x137152b7888 0x137152b9348
    49 {10:20}
    50 True

    三.小时牛刀

    1>.list类实例为什么不可hash?

      1 class list(object):
      2     """
      3     Built-in mutable sequence.
      4     
      5     If no argument is given, the constructor creates a new empty list.
      6     The argument must be an iterable if specified.
      7     """
      8     def append(self, *args, **kwargs): # real signature unknown
      9         """ Append object to the end of the list. """
     10         pass
     11 
     12     def clear(self, *args, **kwargs): # real signature unknown
     13         """ Remove all items from list. """
     14         pass
     15 
     16     def copy(self, *args, **kwargs): # real signature unknown
     17         """ Return a shallow copy of the list. """
     18         pass
     19 
     20     def count(self, *args, **kwargs): # real signature unknown
     21         """ Return number of occurrences of value. """
     22         pass
     23 
     24     def extend(self, *args, **kwargs): # real signature unknown
     25         """ Extend list by appending elements from the iterable. """
     26         pass
     27 
     28     def index(self, *args, **kwargs): # real signature unknown
     29         """
     30         Return first index of value.
     31         
     32         Raises ValueError if the value is not present.
     33         """
     34         pass
     35 
     36     def insert(self, *args, **kwargs): # real signature unknown
     37         """ Insert object before index. """
     38         pass
     39 
     40     def pop(self, *args, **kwargs): # real signature unknown
     41         """
     42         Remove and return item at index (default last).
     43         
     44         Raises IndexError if list is empty or index is out of range.
     45         """
     46         pass
     47 
     48     def remove(self, *args, **kwargs): # real signature unknown
     49         """
     50         Remove first occurrence of value.
     51         
     52         Raises ValueError if the value is not present.
     53         """
     54         pass
     55 
     56     def reverse(self, *args, **kwargs): # real signature unknown
     57         """ Reverse *IN PLACE*. """
     58         pass
     59 
     60     def sort(self, *args, **kwargs): # real signature unknown
     61         """ Stable sort *IN PLACE*. """
     62         pass
     63 
     64     def __add__(self, *args, **kwargs): # real signature unknown
     65         """ Return self+value. """
     66         pass
     67 
     68     def __contains__(self, *args, **kwargs): # real signature unknown
     69         """ Return key in self. """
     70         pass
     71 
     72     def __delitem__(self, *args, **kwargs): # real signature unknown
     73         """ Delete self[key]. """
     74         pass
     75 
     76     def __eq__(self, *args, **kwargs): # real signature unknown
     77         """ Return self==value. """
     78         pass
     79 
     80     def __getattribute__(self, *args, **kwargs): # real signature unknown
     81         """ Return getattr(self, name). """
     82         pass
     83 
     84     def __getitem__(self, y): # real signature unknown; restored from __doc__
     85         """ x.__getitem__(y) <==> x[y] """
     86         pass
     87 
     88     def __ge__(self, *args, **kwargs): # real signature unknown
     89         """ Return self>=value. """
     90         pass
     91 
     92     def __gt__(self, *args, **kwargs): # real signature unknown
     93         """ Return self>value. """
     94         pass
     95 
     96     def __iadd__(self, *args, **kwargs): # real signature unknown
     97         """ Implement self+=value. """
     98         pass
     99 
    100     def __imul__(self, *args, **kwargs): # real signature unknown
    101         """ Implement self*=value. """
    102         pass
    103 
    104     def __init__(self, seq=()): # known special case of list.__init__
    105         """
    106         Built-in mutable sequence.
    107         
    108         If no argument is given, the constructor creates a new empty list.
    109         The argument must be an iterable if specified.
    110         # (copied from class doc)
    111         """
    112         pass
    113 
    114     def __iter__(self, *args, **kwargs): # real signature unknown
    115         """ Implement iter(self). """
    116         pass
    117 
    118     def __len__(self, *args, **kwargs): # real signature unknown
    119         """ Return len(self). """
    120         pass
    121 
    122     def __le__(self, *args, **kwargs): # real signature unknown
    123         """ Return self<=value. """
    124         pass
    125 
    126     def __lt__(self, *args, **kwargs): # real signature unknown
    127         """ Return self<value. """
    128         pass
    129 
    130     def __mul__(self, *args, **kwargs): # real signature unknown
    131         """ Return self*value. """
    132         pass
    133 
    134     @staticmethod # known case of __new__
    135     def __new__(*args, **kwargs): # real signature unknown
    136         """ Create and return a new object.  See help(type) for accurate signature. """
    137         pass
    138 
    139     def __ne__(self, *args, **kwargs): # real signature unknown
    140         """ Return self!=value. """
    141         pass
    142 
    143     def __repr__(self, *args, **kwargs): # real signature unknown
    144         """ Return repr(self). """
    145         pass
    146 
    147     def __reversed__(self, *args, **kwargs): # real signature unknown
    148         """ Return a reverse iterator over the list. """
    149         pass
    150 
    151     def __rmul__(self, *args, **kwargs): # real signature unknown
    152         """ Return value*self. """
    153         pass
    154 
    155     def __setitem__(self, *args, **kwargs): # real signature unknown
    156         """ Set self[key] to value. """
    157         pass
    158 
    159     def __sizeof__(self, *args, **kwargs): # real signature unknown
    160         """ Return the size of the list in memory, in bytes. """
    161         pass
    162 
    163     __hash__ = None
    class list(object):(源码解析)

    2>.functools.lru_cache使用到的functools.HashedSeq类继承自list,为什么可hash?

     1 class _HashedSeq(list):
     2     """ This class guarantees that hash() will be called no more than once
     3         per element.  This is important because the lru_cache() will hash
     4         the key multiple times on a cache miss.
     5 
     6     """
     7 
     8     __slots__ = 'hashvalue'
     9 
    10     def __init__(self, tup, hash=hash):
    11         self[:] = tup
    12         self.hashvalue = hash(tup)
    13 
    14     def __hash__(self):
    15         return self.hashvalue
    class _HashedSeq(list):源码解析

  • 相关阅读:
    Jocke的IOT之路--raspberrypi更换国内镜像
    利用PostMan 模拟上传/下载文件
    Java中的Lambda表达式
    设计模式之Jdk动态代理
    设计模式之代理模式
    Java内存模型及Java关键字 volatile的作用和使用说明
    JVM GC-----4、finalize()方法
    JVM GC-----3、垃圾对象的标记思路(二)
    JVM GC-----2、垃圾对象的标记思路(一)
    JVM GC-----1、垃圾回收算法
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/11219898.html
Copyright © 2020-2023  润新知