V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
imn1
V2EX  ›  Python

有没有办法 hash 一个 object?

  •  
  •   imn1 · 2021-08-30 14:54:37 +08:00 · 2738 次点击
    这是一个创建于 1182 天前的主题,其中的信息可能已经有所发展或是发生改变。
    标题写简单了,实际目的是“识别”一个 object,例如一个函数,依据不同参数,获得不同的唯一识别
    需求是写个 cache,但 @chahe 是内存的,程序结束就销毁了,我需要 pickle 到外部储存,下次运行时,依据该函数的不同参数读取

    寻求一个思路
    第 1 条附言  ·  2021-08-30 16:30:06 +08:00
    举个例子,不一定是这种形式,大致意思

    def funA(x, y, z):
    ...

    fa = partial(funA, x=1, y=2, z=some_object)
    key = hash_method(fa)

    现在就想要这个 key 在下次运行也能相同
    第 2 条附言  ·  2021-08-30 16:37:18 +08:00
    呃,忘了 inspect 这个好东西
    用 inspect.signature 组合一下应该可以 hash,再研究一下
    14 条回复    2021-08-31 12:17:58 +08:00
    malusama
        1
    malusama  
       2021-08-30 14:58:58 +08:00   ❤️ 1
    你把状态保存到外部储存不就好了。 用 redis 之类的储存?
    fgwmlhdkkkw
        2
    fgwmlhdkkkw  
       2021-08-30 15:07:57 +08:00   ❤️ 1
    转成 json,然后对 json 做 hash 。
    xx6412223
        3
    xx6412223  
       2021-08-30 15:15:21 +08:00   ❤️ 1
    不管存哪都要 key 啊 和内外部有啥关系
    eason1874
        4
    eason1874  
       2021-08-30 15:15:44 +08:00   ❤️ 1
    1 、能写到内存就能写到硬盘;
    2 、高级语言都会有一些方法库可以将正在运行的指定的 source code 转换成 string ;

    保存状态一般是保存数据,需要连代码都保存的场景很少很少,你的业务实现可能走了弯路
    janxin
        5
    janxin  
       2021-08-30 15:18:37 +08:00   ❤️ 1
    我猜你可能想要了解__eq__和__hash__
    imn1
        6
    imn1  
    OP
       2021-08-30 15:30:25 +08:00
    @eason1874 #4
    不需要代码,只是参数和函数名,只需要一个标识

    举个例子,目前遇到的:
    机器学习要做大量调参工作,限于机器能力,有些工作并不是一天能够完成的,要分成几个步骤几天完成
    需要把中间结果保存,但是同一个函数参数不同,结果就不同,有可能回过头来重新调取之前某次的中间结果再计算
    例如 funA,funB,funC 要三天完成,但结果不理想,需要 funA,funB1,funC1 再做一次,这时 funA 之前已经计算过了,肯定不想再花一天重新计算,如果 funA 依据参数不同也有 funA1,funA2……自然期望每次都自动保存下来,以后根据函数名+参数就能识别出 cache 来了,funB/funC 也有类似情况
    xmh51
        7
    xmh51  
       2021-08-30 15:41:38 +08:00   ❤️ 1
    @imn1 结果以 key ( hash(函数加入参)) value 的形式存起来能否满足要求? hash 方法是 md5 或者 sha1
    eason1874
        8
    eason1874  
       2021-08-30 15:43:25 +08:00   ❤️ 1
    @imn1 #6 我理解错了,那你的需求还是保存数据,只是不知道怎么实现。

    那可以按 #1 说的做,用 Redis,函数名和参数当 key (太长就取 hash ),开启持久化存储到硬盘,程序结束还是能读回来。启动程序的时候,传参指定初始化数据的 key 去读取。
    imn1
        9
    imn1  
    OP
       2021-08-30 16:00:01 +08:00
    @malusama #1
    redis 有点大,不过我明白你说的,目前想到的也是 记录参数-->对应主键 这个方案
    我只是想看看有没有什么点子能拟合到单一个变量 /字段,这样就能写一个通用的管理类了
    imn1
        10
    imn1  
    OP
       2021-08-30 16:13:48 +08:00
    @xmh51 #7
    这个是我一小时前正在查的方案,只是 md5 还是针对字节 /字串的,我想看看有没有兼容更广的方法
    其实如果内置函数 hash()能每次固定倒是省事,可惜不能

    @eason1874 #8
    虽然写 py 多年,但还是视角局限性很大(一直写客户端的东西),发此帖的目的是想看看有没有人提点一下什么我不知道的函数,例如 contextlib.closing 这么简单的东西也是最近才知道,:苦笑
    hushao
        11
    hushao  
       2021-08-30 16:34:23 +08:00 via iPhone   ❤️ 1
    你自己都提到了 pickle
    O5oz6z3
        12
    O5oz6z3  
       2021-08-30 19:21:24 +08:00   ❤️ 1
    没做过,想到几个麻烦的思路,权当参考。
    1. 用环境变量 pythonhashseed 固定 hash()的结果,但是未必可靠。
    2. 感觉本质上和 #5 楼说的一样,根据你的具体情况来决定将函数的哪些属性作为特征来哈希。比如说,包含函数的源码行数与文件位置、函数名、参数签名等等。

    将函数的几个属性转为元组也能直接用作哈希,或者进一步将元组用 str()字符串化后再用 md5 之类的哈希函数。
    如果用字典,就 json.dumps(sort_keys=True)之类的(没用过但听说还有 frozenset(dict.items())、deepdiff.DeepHash(dict)[dict]、frozendict 之类的)
    XD2333
        13
    XD2333  
       2021-08-30 21:29:59 +08:00   ❤️ 1
    重写__eq__和__hash__?
    ysc3839
        14
    ysc3839  
       2021-08-31 12:17:58 +08:00
    你能保证 pickle 后得到的数据是一一对应的话,对 pickle 后得到的数据进行 hash 就好了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5939 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 03:25 · PVG 11:25 · LAX 19:25 · JFK 22:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.