# 其他第三方包 ```{toctree} ./mypy.md ``` ## datatype ### bitstring [官网](https://github.com/scott-griffiths/bitstring) 把二进制转化成01 ```python from bitstring import BitArray BitArray(b"123").bin # '001100010011001000110011' BitArray(HexBytes("0x7f")).int # 127 01111111 BitArray(HexBytes("0x80")).int # -128 10000000 ``` ### [hexbytes](https://hexbytes.readthedocs.io/en/stable/) 处理字符串和十六进制 ```python from hexbytes import HexBytes HexBytes(b"123") // HexBytes("0x313233") HexBytes(b"123").hex() // "0x0123" HexBytes("123") // HexBytes("0x0123") HexBytes("123").hex() // "0x313233" ``` * len 2个hex为1个长度 * slice `HexBytes("0xffff")[0:1] == HexBytes("0xff")` * getitem `HexBytes("0xffff")[0] == 255` ## 开发工具类 ### colorlog [example](./test_colorlog.py) ```python import logging import colorlog handler = colorlog.StreamHandler() handler.setFormatter(colorlog.ColoredFormatter( "%(log_color)s%(levelname)s:%(name)s:%(message)s" )) logging.basicConfig(level=logging.DEBUG, handlers=[handler]) logger = logging.getLogger(__name__) logger.debug("info") logger.info("info") logger.error("error") ``` [github](https://github.com/borntyping/python-colorlog) 带日志的streamlog ### mistletoe 解析markdown [github](https://github.com/miyuchina/mistletoe) ## 未分类 ```{toctree} :maxdepth: 1 ./exchangelib.md ./openpyxl.md ./beautifulsoup.md ./click.md ./flask.md ``` ```{toctree} :maxdepth: 1 ./imapclient.md ./ipdb.md ./jinjia.md ./pandas.md ./peewee.md ./pyenv.md ./pylint.md ./requests.md ./rsa.md ./visidata.md ./wechatpy.md ``` ## celery 用来执行异步脚本, 这个软件在linux-reference里面 [github在线链接](https://github.com/ramwin/linux-reference#celery) ## 7z [官网](https://github.com/miurahr/py7zr) ```python import py7zr archive = py7zr.SevenZipFile('sample.7z', mode='r') archive.extractall(path='/tmp') ``` ## 网络 ```{toctree} ./scrapy/README.md ./scrapy/spider.md ./scrapy/log.md ./scrapy/selector选择器.md ``` ## 性能 ### optunar 优化参数 [./test_optunar.py](./test_optunar.py) ## mysql ```{toctree} ../mysql.md ``` ## mongoengine ```{toctree} ./mongoengine.md ``` ## pillow ```{toctree} :maxdepth: 1 ../pillow.md ``` ## [diff-match-patch](https://github.com/google/diff-match-patch) 用来比较文字的不同 * 用法 ``` >>> from diff_match_patch import diff_match_patch >>> dmp = diff_match_patch() >>> dmp.diff_main('123', '22') [(-1, '1'), (1, '2'), (0, '2'), (-1, '3')] >>> dmp.diff_prettyHtml(dmp.diff_main('123', '223')) '1223' ``` * 效果 1223 ## [filelock](https://github.com/benediktschmitt/py-filelock) from filelock import Timeout, FileLock lock = FileLock(path) try: lock.acquire(timeout=0) except Timeout: pass ## flockcontext [github](https://github.com/AntoineCezar/flockcontext) ``` pip3 install flockcontext from flockcontext import FlockOpen with FlockOpen(Path, "w", timeout=3600) as lock: lock.fd.write("Locked\n") ``` ## [git](https://gitpython.readthedocs.io/en/stable/tutorial.html) 处理git用 * 克隆代码 ```python from git import Repo from pathlib import Path Repo.clone_from(url, to_path) git.Repo.clone_from(url, to_path, recurse_submodule=True) ## 指定密钥来克隆 repo = git.Repo.init(Path("target")) with repo.config_writer() as writer: writer.set("core", "sshCommand", "ssh -i <自定义密钥>") ``` * 基础代码 ```python sudo pip3 install gitpython from git import Repo repo = Repo() for tag in repo.tags: print(tag.name, tag.commit) for commit in repo.iter_commits(max_count=10): print(commit.hexsha, commit.message, commit.author.name, ) ``` * 运行git命令 ```python import git repo.git.rebase cmd = git.cmd.Git() cmd.execute('git lfs ls-files -l') try: repo.git.merge() # 合并分支 except git.GitCommandError: raise ``` ### 执行命令 * show 查看某个文件的内容 ``` repo.git.show(f"{commit}:README.md") => str ``` ### commit ``` commit = next(repo.iter_commits("master", before=datetime.date(2022, 1, 1))) # 获取元旦最后一个提交 commit.commitded_date datetime.datetime(2020, 6, 19, 9, 46, 9, tzinfo=) commit.hexsha ``` ### remote ``` origin = repo.create_remote("origin", "git@github.com:ramwin/python-reference.git") origin.pull() ``` ## Humanfriendly ``` Humanfriendly.parse_size("10M") // 10_000_000 Humanfriendly.parse_size("10M", binary=True) // 1024 x 1024 x 10 ``` ## [imapclient](imapclient.md) 很好用的邮件客户端 * [ics](https://pypi.org/project/ics/) *日历,行程 calendar* * [ipdb](./ipdb.md) *断点来检测查看源码和运行状态* ## PID 流程控制算法 ```python from simple_pid import PID from exponential_counter import LinearCounter def test_time2(): print("我们提供一个自己的时间函数,每次加1") pid = PID(1, 0.1, 0.05, time_fn=LinearCounter()) value = -200 for _ in range(3): delta = pid(value) value = value + delta print("增加%f 变成 => %f", delta, value) ## 我们提供一个自己的时间函数,每次加1 ## 增加%f 变成 => %f 220.0 20.0 ## 增加%f 变成 => %f -13.0 7.0 ## 增加%f 变成 => %f 10.950000000000001 17.950000000000003 ``` ## [pip][pip] *快速安装包* * [官网](https://pip.pypa.io/en/stable/) * [配置文件](https://pip.pypa.io/en/stable/user_guide/#config-file) * 使用其他源 ```bash pip install --extra-index=https://pypi.tuna.tsinghua.edu.cn/simple --extra-index=https://pypi.python.org/ django pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django==1.11 pip install -i https://pypi.org/simple django==1.11 sudo pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple # 设置清华的源 export LC_ALL="en_US.UTF-8" # 出现乱码 export LC_CTYPE="en_US.UTF-8" ``` * 安装开发版 `pip install --no-index --no-build-isolation -e .` ## psutil [获取系统信息](https://psutil.readthedocs.io/en/latest/) ```python import psutil psutil.net_if_addrs() all_ips = [ i.address for i in itertools.chain(*psutil.net_if_addrs().values()) ] ['169.254.139.78', '4c:cc:6a:47:6a:6f', '169.254.51.28', '90:61:ae:bb:31:8f', '127.0.0.1', '::1', '00:00:00:00:00:00', '169.254.162.106', '00:ff:cc:e9:90:30', '192.168.0.102', '90:61:ae:bb:31:8b', '169.254.220.176', '90:61:ae:bb:31:8c', '169.254.22.106', '92:61:ae:bb:31:8b'] ``` * 获取CPU信息 ```python3 psutil.cpu_percent() => 3.5 # 所有cpu平均3.5% ``` * [获取内存信息](https://stackoverflow.com/questions/938733/total-memory-used-by-python-process) ```python3 import os, psutil process = psutil.Process() print(process.memory_info().rss) # in bytes ``` ## pysrt [官网](https://github.com/byroot/pysrt) * 基础 ``` import pysrt subs = pysrt.open('srt.srt', encoding='utf8') first_sub = subs[0] first_sub.text = "hello world" first_sub.start.seconds = 20 first_sub.shift(seconds=2) first_sub.start += {'seconds': -1} subs.shift(minutes=1) subs.shift(ratio=25/23.9) # convert a 23.9 fps subtitle in 25fps del subs[12] part = subs.slice(starts_after={'minutes': 2, 'seconds': 30}, ends_before={'minutes': 3, 'seconds': 40}) part.shift(seconds=-2) subs.save('other/path.srt', encoding='utf8') ``` ## redis [本地](http://localhost:18002/redis/redis.html) [github](https://github.com/ramwin/linux-reference/blob/master/redis/redis.md) ## requests-cache 利用缓存来保存文件, 还可以指定用哪个key ```python3 import requests_cache def timekey(request: PreparedRequest, **kwargs): return parse_qs( urlparse(request.url).query )["time"][0] session = requests_cache.CachedSession( 'demo_cache', backend="filesystem", use_cache_dir=False, allowable_methds=["GET"], key_fn=timekey, ) ``` ## retry ``` from retry import retry @retry(delay=0.1, tries=3, logger=LOGGER) def run(): if time.time() - start >= 0.1: print("OK") return True print("FAIL") raise ValueError("请等等") ``` ## web3 ### [eth_utils](https://eth-utils.readthedocs.io/en/stable/) ``` from eth_utils.address import to_checksum_address ``` ### hexbytes * hexbytes.main.HexBytes ``` a == HexBytes(b"23") b"2" == 50 == '0x32' a = HexBytes("0x3233") a.hex() # "0x3233" str(a) # "b'23'" ``` ### eth * eth.subscribe ``` { 'jsonrpc': '2.0', 'method': 'eth_subscription', 'params': { 'subscription': '0x83d5de89ec40acb9929bbb809caa6f4c', 'result': { 'address': '0x6a091a3406e0073c3cd6340122143009adac0eda', # pair address 'topics': [ '0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822', # topics, v2_swap '0x000000000000000000000000d9e1ce17f2641f24ae83637ab66a2cca9c378b9f', # sender '0x0000000000000000000000002c678004af4c1e217d9ed8baabd4454406ceb63d', # receiver ], 'data': ( '0x' '0000000000000000000000000000000000000000000000000000000000000000' # amount0In '000000000000000000000000000000000000000000000000225ac0e25efff07a' # amount1In '0000000000000000000000000000000000000000000000025f76668b7ad2b42f' # amount0Out '0000000000000000000000000000000000000000000000000000000000000000' # amount1Out ), 'blockNumber': '0x11cca4f', 'transactionHash': '0xe51d8ecfb4fffe4b26f87b4ff2894e8c4dcfed4dd2a42b8af93bc3f90e347d97', 'transactionIndex': '0x72', 'blockHash': '0x5a1f1a86651bc0fa04b8a219a6612e17ef6cc224bb7abe8f09c57324eddb1b5e', 'logIndex': '0x108', 'removed': False} }, 'time': 1701100620 } ``` * web3.eth.get_transaction ``` AttributeDict({ 'blockHash': HexBytes('0x7c15a5dc5ae...2ff3fc6'), 'blockNumber': 18664014, 'from': '0xDF9f0598E04DccdD941462De4fA6B915D5bb7784', 'gas': 213168, 'gasPrice': 43106689045, 'maxFeePerGas': 74346949956, 'maxPriorityFeePerGas': 5000000000, 'hash': HexBytes('0xbff5390790e441959364cb8c7d1ac426de832d65a947f2aad069527a506c7318'), 'input': HexBytes('0x8600c0fe...0000000000'), 'nonce': 66, 'to': '0x2C2C82e7CAf5F14e4995c366D9DB8CdFdf7677E3', 'transactionIndex': 19, 'value': 30000000000000000, 'type': 2, 'accessList': [], 'chainId': 1, 'v': 0, 'r': HexBytes('0x7e561ae149d...c46ab87b61ec'), 's': HexBytes('0x5a483194f03...710d52f97adf')} ``` ### eth_typing * eth_typing.evm.ChecksumAddress [pip]: https://pip.pypa.io/en/stable/user_guide/#config-file