标签 python 下的文章

先说结论:只要文件是同个文件,hash是一致的。

Linux

md5sum filepath

#md5sum 01000.chunk 
ae2056ca156511f3a8223e2a4599b7bf  01000.chunk

PHP

md5_file(filename);

<?php
$file = "01000.chunk";
$md5 = md5_file($file);
var_dump($md5);
//string(32) "ae2056ca156511f3a8223e2a4599b7bf"
?>

Python

这个稍微复杂点,要自己实现,而且执行起来效率貌似也有点低。不清楚为何,按理说所有方法都要读取完整文件效率应该相差不大才对,可能是我方法不对。


import hashlib

fname = "01000.chunk"

def md5_file(filename):
    m = hashlib.md5()   #创建md5对象
    with open(filename,'rb') as fobj:
        while True:
            data = fobj.read(4096)
            if not data:
                break
            m.update(data)  #更新md5对象
    return m.hexdigest()    

hash = md5_file(fname)
print(hash, fname) 

设想在入群验证的机器人中要求新用户输入特定的成语,由于用户可能来自港澳台或海外地区的华人,所以需要考虑到他们的输入法是繁体的情况。

zhconv 是找到的比较简易的解决办法, 而且 python2 / 3 都有支持

安装方法

pip3 install zhconv

使用

from zhconv import convert

str_big5 = '恭喜發財'
str_zhcn = convert(str_big5, 'zh-hans')
print(str_zhcn)

恭喜发财

参考文

先声明,这不是教学也没有自称是最正统王道的做法。只是适用于我当前项目的情况。

背景:一个后台的守护进程,会对导入的批量文件进行轮询及列队处理。
这些目标文件可能有各种预期外的格式、数据类型不正确导致py崩溃中途退出。造成了队列堵塞

当发现堵塞时,手动去运行脚本可以查看到有问题的关键文件。但想找个办法让遇到问题是能跳过不阻塞队列,但保留错误信息到日志以便追查处理。

以下是我的处理办法。核心是用 try/exceptionlogging 捕获异常写入自定义日志文件。

import logging

# 设置输出错误日志
logging.basicConfig(filename='pyerr.log', filemode='w')

# 扫描待处理的目录,查找 docx文件
filelist = os.listdir(scan_path)

for dfile in filelist:
    if dfile[-5:].lower() == ".docx":
        try:
            imp_result = mod_doc.import_db(scan_path+dfile) #这步是容易出现异常的导入复杂操作
            # 导出处理结果的业务逻辑 略

        except: #把异常写入日志文件
            s = traceback.format_exc()
            logging.error(dfile+'\n'+s)

    else:
        print("non docx file, skip:"+dfile)

仅作备忘,有关异常处理和日志处理的用法这里不展开说明。

业务逻辑中处理完毕的文档会被转移归档保存,所以剩下在目录里的则是异常的文件。
如想避免异常文件每轮的轮询仍被执行, 可以转移到特定文件夹并修改 logging.basicConfig 的 filemode 改为 'a' 使多个异常文档的错误信息不会被覆盖。

运行了几个python后台守护进程,需要重启的时候不能简单 killall python 很容易会误杀其他服务
所以备忘以下的脚本

已验证有效

#!/bin/sh

function PidFind()  
{
    PIDCOUNT=`ps -ef | grep $1 | grep -v "grep" | grep -v $0 | awk '{print $2}' | wc -l`;  

    if [ ${PIDCOUNT} -gt 1 ] ; then  
        echo "There are too many process contains name[$1]"  
    elif [ ${PIDCOUNT} -le 0 ] ; then  
        echo "No such process[$1]!"  
    else  
        PID=`ps -ef | grep $1 | grep -v "grep" | grep -v ".sh" | awk '{print $2}'` ;  
        echo "Find the PID of this progress!--- process:$1 PID=[${PID}] ";  

        echo "Kill the process $1 ...";          
        kill -9  ${PID};  
        echo "kill -9 ${PID} $1 done!";  
    fi  
}
#查找并kill掉 带有 newdoc.daemon 名称的进程
PidFind newdoc.daemon

#restart daemon
/path/to/startscript/chkdaemon.sh

当搜索结果不唯一时,脚本也会拒绝执行杀进程

参考文:https://jingyan.baidu.com/article/b7001fe1a5dbc40e7382dd75.html

备忘,当对一个有唯一索引字段的表做插入操作INSERT INTO 时做遇到冲突则更新的逻辑ON DUPLICATE KEY UPDATE
想知道此时是否仍然能够获取到 操作的行的id值db.lastrowid

sql = "INSERT INTO `mTable`(`id`, `tfsn`)  " \
          "VALUES(%s, %s) " \
          "ON DUPLICATE KEY UPDATE `tfsn`=VALUES(`tfsn`);"

vals = (id, tfsn)

try:
    db.execute(sql, vals)

    new_cid = db.lastrowid
    print("tfid:", tfid) #如果触发了update 可以获得id值?

结论是,能,也可能不。
当触发update 有内容变更时,可以获得 id值;
当update的内容新旧完全一致前后没有变化的话,mysql会认为没有任何行被更新。所以返回的 id 会是0