跳到主要内容

博客

代码人生:编织技术与生活的博客之旅

复制的每天都在列计划,却总是完不成咋整(# ̄~ ̄#)的笔记,推荐这个视频和这个up主,是个非常优秀值得学习的明灯。

  • 明确优先级 (人生课题顺序)。
  • 每天都会出现很多突发事件,我们怎样选择? 这关系到 priority ranking
  • 所有事件按照和人生目标有关无关分类。
  • 没有主体性的人很容易被影响。
  • 要留有余白buffer zone —>留下给心情不好的时间反而能够更快修复

制定计划的注意事项

  • 有明确的结束时间
  • 不要用todo list,用有优先级的list (Burner list)重
  • 要的事情不要超过2件,最多三件
  • 这两件事最好是不同领域的(比如说人生目标、工作)
  • 写下要做的事情,并写下做这件事的目的。并把目的融入到最后环节。
  • 将这两件事分层,写action item (e.g.学多少时间,学的时候排除干扰。),而非目标本身。
  • 就算这一件事都没完成,你也清楚自己的可支配时间花在了正确的道路上

公开承诺

  • 和盆友每50分钟通报进度(不聊天)
  • 早中晚一天至少三次∶宣言【现在我要做什么】--> 把自己从烦扰中拉回来

做 Done list --> 反馈、什么做完了


这些确实是清单上的项目。制作一个PowerPoint演示文稿的前十张幻灯片。与供应商进行一次对话。写500字的公司通讯。简单的任务。检查表上的项目。 另外,**记得计算出你一天能完成多少个明确的目标,然后每天都完成这个数量的目标。**如果它出现在你的清单上,你就对自己说了算。要么把它从清单上划掉。要么--当挑战发现比预期的难得多时,把它分解成一个较小的任务,完成这个较小的任务,然后把剩下的任务移到明天的清单上。 如果你完成了今天明确目标清单上的所有任务,这意味着你离你的高难度目标又近了一步,这意味着你正在执行任务,这意味着你的内在驱动力正在做他们的工作。在这个清单上划撕一项,就能得到一点多巴胺;再划掉一项,就能多得到一点多巴胺。一次一个小赢,就是这样的。将小胜叠加在小胜之上-尤其是当其中的几场小胜产生心流时--就是你获得动力的方式。

制定计划的时间

  • 头一天结束工作的时候

培养主体性的方法

  • 【弱点】是宝物。通向幸福的捷径。
  • 对十年后实现梦想的自己做【英雄采访】∶以成功为大前提来做。

内向者的工作方式

  • 每天要有什么都不做的时间,即使非常短暂
  • 还没做完的任务,写下来确切自己打算完成的日期。
  • 检查邮件和电话的时间集中在一起。
  • 减少对于日常小事的选项

finally some random thoughts

  • 照顾好分钟,时钟会照顾好自己
  • 有没有一种选项,只是为了做而做。to do sth in order to do it.
阅读笔记阅读需 3 分钟

  • 提供一些小的服务
  • 收费
  • 欢迎联系 📞

删除百度贴吧历史

  • 对百度贴吧的数据进行批量删除服务 🗑️
  • 联系后加微信 扫二维码远程登录解决
  • 可删除
    • 题帖
    • 回复
    • 关注的吧
    • 关注
    • 粉丝
  • 非常便宜 💸

少量爬取小说

  • 提供小说爬取服务 📚
  • 十到二十本
  • 不保证给的名字的小说都有
  • 找不到的话 不收费
  • 无 ip 池 做不到大批量 见谅

Job 扫描助手

  • 提供一个 12h/次 对 Upwork 的工作机会搜索 💼
  • 会通过 ai 进行您提供的简历的匹配和过滤
  • 针对简历的 ai 过滤搜索
  • 按月收费

自动化脚本程序

  • 提供对 execl 的自动化程序 🤖
    • 自动整理数据 计算 平均 画图 发邮件 等功能
  • 参考
    • 根据销售数据 画比例图 生成报告 📊
    • 按工资表发工资条邮件 📧

基于 python 的后端服务

  • 如果需要定制 app 或者网页 🐍
  • 还需要一个前端(移动端 or 网页端)

基于 tradingView 的量化交易

  • 📈

  • 常规程序开发都可以聊一聊 🗣️
  • 但是请你需求明确
  • 最好把需求写成有写成文档 📝

联系方式 📬

随笔阅读需 2 分钟

  • 这是网盘爬取的部分记录,很多坑,分享一下避免大家采坑。
  • 后续发现网盘有网页版本,在安装能 root 的 Android 模拟器后,放弃通过 app 爬。

Fiddler

教程

  • 电脑管家下的 Fiddler 4.0
    • Fiddler Anywhere 只找到苹果的破解版
  • 允许远程连接
    • 更改 fiddler 端口后要重启软件
  • 手机设置
    • 证书安装
    • 卸载方式
      • 搜索 加密与凭据
      • 用户凭据 找到自己命名的凭据 (fiddler) 点击删除

打开网盘后 无连接

走 fiddler 后,app 打开显示无网络。用 adb 查看日志,找到如下错误:

06-06 19:09:03.624 28223 28223 W System.err: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

是因为,fiddler 装的证书不是根证书,app 不认可。 改为弄根证书需要手机 root,懒得弄了。

装安卓虚拟机

考虑使用安卓模拟器

  • 夜神模拟器
    • hyper-v 冲突
  • bluestacks
  • 天天模拟器
    • 启动不了
    • 安装时蓝屏

卸载某个模拟器后 dll 乱了

无效的 wechatwin.dll 文件 errcode:126, 点击“确定”下载最新版本

  • 微信打不开 怀疑是某个模拟器卸载的时候 把系统的 dll 一起
  • 修复方法参考

按 Win + S 键搜索栏输入 CMD,以管理员身份打开 “命令提示符” 输入命令:

sfc /SCANNOW

等待扫描结束:

Dism /Online /Cleanup-Image /ScanHealth

等进度条走完,再次打开微信,看是否能够正常打开。如果能正常打开,重启电脑再看是否能打开微信,如果重启之后还能正常打开微信等其它软件,说明此问题就修复了。

Hyper-V + Visual Studio 跑 Android 模拟器

参考 用 Xamarin 的模拟器。

安装 Visual Studio 2022 一样可以

  • 打开 SDK 管理器后 提示:
    • Loading SDK component information failed. Please retry
    • 加载 SDK 组件信息失败 请重试
    • must not be an empty string forPath

通过点击:工具 - 选项 - 搜索 Android - Xamarin Android 设置 点击确定后就能找找到位置了。

下载 SDK 需要全局翻墙。

  • 爬完后注意存档位置 方便后续删除
    • C:\Users\xxx\AppData\Local\Xamarin\Mono for Android\Archives

如此,终于有一个能用的,和 hyper-v 不冲突的 Android 模拟器了。

到这里后,发现有网页版本,满足需求,放弃了 app 爬取。


询问大佬们的解决方案

项目阅读需 3 分钟

老方案

save_dir = os.path.join(os.path.expanduser("~"), "Pictures", "wallpaper")
os.makedirs(save_dir, exist_ok=True)

新方案

In [16]: import ctypes
...: from ctypes.wintypes import MAX_PATH
...:
...: dll = ctypes.windll.shell32
...: buf = ctypes.create_unicode_buffer(MAX_PATH + 1)
...: for i in range(100):
...: if dll.SHGetSpecialFolderPathW(None, buf, 0x0000 +i, False):
...: print( 0x0000 +i,buf.value)
...: else:
...: pass
...: # print("Failure!")
...:
0 C:\Users\tmp_user\Desktop
2 C:\Users\tmp_user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs
5 E:\Users\tmp_user\Documents
6 E:\Users\tmp_user\Favorites
7 C:\Users\tmp_user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
8 C:\Users\tmp_user\AppData\Roaming\Microsoft\Windows\Recent
9 C:\Users\tmp_user\AppData\Roaming\Microsoft\Windows\SendTo
11 C:\Users\tmp_user\AppData\Roaming\Microsoft\Windows\Start Menu
13 E:\Users\tmp_user\Music
14 E:\Users\tmp_user\Videos
16 C:\Users\tmp_user\Desktop
19 C:\Users\tmp_user\AppData\Roaming\Microsoft\Windows\Network Shortcuts
20 C:\WINDOWS\Fonts
21 C:\Users\tmp_user\AppData\Roaming\Microsoft\Windows\Templates
22 C:\ProgramData\Microsoft\Windows\Start Menu
23 C:\ProgramData\Microsoft\Windows\Start Menu\Programs
24 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
25 C:\Users\Public\Desktop
26 C:\Users\tmp_user\AppData\Roaming
27 C:\Users\tmp_user\AppData\Roaming\Microsoft\Windows\Printer Shortcuts
28 C:\Users\tmp_user\AppData\Local
29 C:\Users\tmp_user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
30 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
31 E:\Users\tmp_user\Favorites
32 C:\Users\tmp_user\AppData\Local\Microsoft\Windows\INetCache
33 C:\Users\tmp_user\AppData\Local\Microsoft\Windows\INetCookies
34 C:\Users\tmp_user\AppData\Local\Microsoft\Windows\History
35 C:\ProgramData
36 C:\WINDOWS
37 C:\WINDOWS\system32
38 C:\Program Files
39 E:\Users\tmp_user\Pictures
40 C:\Users\tmp_user
41 C:\WINDOWS\SysWOW64
42 C:\Program Files (x86)
43 C:\Program Files\Common Files
44 C:\Program Files (x86)\Common Files
45 C:\ProgramData\Microsoft\Windows\Templates
46 C:\Users\Public\Documents
47 C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools
48 C:\Users\tmp_user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Administrative Tools
53 C:\Users\Public\Music
54 C:\Users\Public\Pictures
55 C:\Users\Public\Videos
56 C:\WINDOWS\resources
59 C:\Users\tmp_user\AppData\Local\Microsoft\Windows\Burn\Burn

整合以后

def get_default_save_dir(dir_name:str= "Pictures"):
# windows platform
res_path = os.path.join(os.path.expanduser("~"), dir_name)
if os.name == "nt":
import ctypes
from ctypes.wintypes import MAX_PATH
...:
dll = ctypes.windll.shell32
buf = ctypes.create_unicode_buffer(MAX_PATH + 1)
for i in range(100):
if dll.SHGetSpecialFolderPathW(None, buf, 0x0000 +i, False) and dir_name in buf.value:
return buf.value
return res_path
Python阅读需 1 分钟

常规升级

  1. 升级 windows11 Windows11InstallationAssistant.exe 这个网站下载升级助手。双击升级。
  2. 升级 wsl,update 时建议全局。wsl --update & wsl --shutdown 目前还没研究出怎么玩 GUI。
  3. 装 wsa
    3.1 add-appxpackage MicrosoftCorporationII.WindowsSubsystemForAndroid_1.7.32815.0_neutral___8wekyb3d8bbwe.Msixbundle(tg 群 有下载)
    3.2 Windows 11 运行安卓子系统安装教程 安装酷安

升级后的一些定制化操作

  1. 个性化 > 任务栏 > 任务栏行为 - 任务栏对齐方式 左
  2. 个性化 > 颜色 > 选择模式 - 自定义 & 选择你的默认 Windows 模式 深色
  3. 重装 PowerToys,新版本建议在 microsoft store 下载。
  4. 删掉 TranslucentTB,从 microsoft store 下载。
  5. 任务栏设置 > 任务栏项 - 关闭聊天, 关闭搜索
  6. 在语言里先增加拼音输入法,然后再删掉拼音输入法,就只有 qq 输入法了。可能会造成闪屏。
  7. 左下角小组件设置一下。

win11 更新后资源管理器不断重启卡死的解决办法

关键词:wsl taskbar all icon flash windows 11 任务栏闪烁

震惊!竟然是 wsl 的锅,解决方法:wsl --shutdown`

根据 帖子,bug 已经在 wslg-issue 里提出,并已经修复。目前有个临时解决方案。

修改 %USERPROFILE%\.wslconfig

[wsl2]
guiApplications=false

然后重启 wsl: wsl --shutdown

解决问题

MicroSoft store 慢

在国内不要开代理,速度就上去了。

win11 右键默认显示更多选项


  • 下载 Windows 11 Classic Context Menu 后,打开则可以看到三个选项,分别对应“经典右键菜单”、“默认右键菜单”和“重启 explorer.exe”。
  • 可以自由切换经典的菜单样式。
随笔阅读需 2 分钟


根据 https://www.v2ex.com/t/858946?p=1#r_11758561

https://us.flow.microsoft.com 登陆这个,然后新建一个流把收到的邮件放到收件箱就行了。看下面的文章有详细说明步骤。 反正 Outlook 的邮箱过滤功能就是一坨屎。

https://zhuanlan.zhihu.com/p/403170937

虽然最开始会进入垃圾邮箱,过一段时间就会移动到收件箱了。


搬运知乎原贴

利用Power Automate创建流来把归类到垃圾邮件里面的邮件重新移到收件箱,虽然同样的会错过规则,但至少普通邮件不受影响。

首先打开Power Automate然后登陆,直接百度就行,国内委托给世纪互联运营所以应该没问题。

1

我的流》新流》自动化云端流

2

流名称选自己喜欢的就好,注意触发器一定要http://outlook.com的新邮件触发器。如果是office 365 outlook的触发器后面会提示说你账号不存在,只有工作账号和学生账号(Exchange)可用。

3

文件夹》垃圾邮件》新步骤

4

选择操作》http://outlook.com(和前面一样注意不要选到Office 365 Outlook了)

5

搜索“移动”》选择“移动电子邮件”

6

点选消息ID文本输入框》选择消息ID

6

点选文件夹》选择收件箱(或者其它文件夹都可)

7

点击保存即可

8

之后可以拿别的邮箱塞一封垃圾邮件试试。比如下面这种标榜自己就是垃圾邮件的邮件

标题:spam

正文:spamspamspamspamspam

我的情况是先被塞到垃圾邮箱里,过一会就被移出来了。

不想翻垃圾箱的同志们可以试试,上面原文链接里面还有添加筛选的功能,我垃圾邮件不多,广告邮件都建立了规则自动归类所以还OK。

而且这是在新邮件进来的时候才执行,且邮件ID唯一,所以自己移动到垃圾邮件不受影响。


先说结论:使用 outLook 网页版 就 ok 了。

最近因为调试 github action , 疯狂发报错邮件,导致 outlook 判定 github 为垃圾邮件,全部发到 outlook 垃圾箱里了。

我用的是 outlook 客户端 (outlook client)。网上已经明确说,客户端设置的是个 bug,垃圾邮件过滤规则不生效。对客户端已经摆烂了。

有效方案:完全不使用 outlook 客户端, 用 网页版 outlook 邮箱

在已关闭 outlook 垃圾邮箱 筛选器 的情况下,就不会默认放进垃圾邮件。 - 关闭客户端后,担心没有提示的,建议在设置打开 邮件桌面提醒

- 客户端与网页端的主要区别是邮件过滤规则中,不能开启标记邮件并提示到 Microsoft To Do List

结合之前还出了一个 office 365 网页版本 的推行。

看来巨硬已经完全放弃客户端了。

屁大点事阅读需 3 分钟

  • 参考 (doc just the docs 主题蛮好看的)
  • 基本不用,现场不方便改代码 debug。
python -m pdb my_script.py

cat my_script.py

import pdb

def make_bread():
pdb.set_trace()
return "I don't have time"

print(make_bread())

命令列表:

  • c(continue): 继续执行
  • w(where): 显示当前正在执行的代码行的上下文信息
  • a(args): 打印当前函数的参数列表
  • s(step): 执行当前代码行,并停在第一个能停的地方(相当于单步进入)
  • n(next): 继续执行到当前函数的下一行,或者当前行直接返回(单步跳过)

单步跳过(next)和单步进入(step)的区别在于,单步进入会进入当前行调用的函数内部并停在里面,而单步跳过会(几乎)全速执行完当前行调用的函数,并停在当前函数的下一行。

Python阅读需 1 分钟

In [1]: 0.1 + 0.2 == 0.3
Out[1]: False

In [4]: round(2.675, 2)
Out[4]: 2.67

浮点数的二进制表示

2.25 的二进制表示是? 整数部分的二进制表示为 10, 小数部分我们逐步来算 0.25 2 = 0.5 整数部分取 0 0.5 2 = 1.0 整数部分取 1 所以 2.25 的二进制表示为 10.01

0.1 的二进制表示是 0.00011001100110011001100110011……0011 0011 作为二进制小数的循环节不断的进行循环。

浮点数的二进制存储

Python 和 C 一样,采用 IEEE 754 规范来存储浮点数。IEEE 754 对双精度浮点数的存储规范将 64 bit 分为 3 部分。

decimal 模块

我一开始的使用方式是

# 错误用法
In [14]: Decimal(2.675) * Decimal(1.2)
Out[14]: Decimal('3.209999999999999668043315637')
# 正确的用法是
In [15]: Decimal('2.675') * Decimal('1.2')
Out[15]: Decimal('3.2100')
屁大点事阅读需 1 分钟

开始使用 note 做笔记后,大事小事都记录在笔记里,已经不怎么屁大点事都会发博客了。

痛点在于,需要手动同步文章和关联的图片到博客项目,push 到 github 后,触发自动部署更新静态页面。

想做一个类似点击公开,自动分享到博客项目的持续继承功能。

设想如下:

  • 本身 markdown 有 attribute 数据。
  • 增加 article: true 表示是需要发表到博客的项目。
  • 每次提交的时候,通过 github 提供的免费的 CI 功能 actions,扫描带有 article: true 的 markdown 文件,发送到博客项目单独分支。
  • 博客项目生成一个 pr , 方便检查文章格式等,通过人工审核后,同意合并至 master 分支,更新静态页面。

下面讲讲各个步骤细节,方便大佬们抄作业。

博客项目 同步相关

博客相关 actions 配置

  • 需要获取一个提交用的 github token , 我这里设置的名称为 blog_sync
name: sync-note
on:
push:
branches:
- develop # Change this to your default branch
paths:
- "note/docs/articles/*.md"
jobs:
make-html-send-email:
name: make-time-file
runs-on: ubuntu-latest
steps:
- name: get blog repository
uses: actions/checkout@master
- run: |
cd ..
git config --global user.email "z740713651@outlook.com"
git config --global user.name "AngusWG"
git config --global credential.helper cache
git clone https://${{secrets.blog_sync}}@github.com/AngusWG/AngusWG
cd AngusWG
git checkout dev_auto 2>/dev/null || git checkout -b dev_auto

- name: cd into note repo
run: cd ../WG & pwd

- name: install python script requirement
run: pip install .

- name: run the script sync note to blog repo
run: python wg sync_note note /home/runner/work/WG/AngusWG/docs

- name: commit note
run: |
cd /home/runner/work/WG/AngusWG
git add .
git commit -m "sync note $(date +"%Y-%m-%d %H:%M:%S")" || true
git push origin dev_auto

同步博客的 python 脚本

  • 直接用的话 需要做入参适当修改。
  • 设置 article: true 的文章会自动发表到博客。
  • 当 date 不一样时,会自动同步笔记的内容到博客。

需要笔记文件夹和博客有以下目录结构

  • sorce_note_dir: 笔记文件夹
    • articles: 可以发布的文章文件夹
      • a.md (article: true)
      • b.md (article: true)
      • c.md (article: false)
    • images: 笔记图片文件夹
      • a1.png
      • a2.png
      • c1.png
  • target_note_dir: 笔记文件夹
    • articles: 已经发布的博客文件夹
      • a.md (article: true)
      • b.md (article: true)
    • images: 博客图片文件夹
      • a1.png
      • a2.png
#!/usr/bin/env python
# encoding: utf-8
# @Time : 2022/04/18 18:22:22
# @author : zza
# @Email : z740713651@outlook.com
# @File : sync_markdown_note.py
"""同步笔记用"""

import os
import frontmatter
import re
import shutil

default_dir = "articles"
article_attribute = "article"

def _need_sync(file_path: str, output_dir: str) -> bool:
"""
判断是否要同步笔记

1 笔记里存在 属性 publish:true
2 笔记日期 > 已发布笔记日期
"""
post = frontmatter.load(file_path)
# publish
if not post.get(article_attribute):
return False
# update date
old_file = os.path.join(output_dir, default_dir, os.path.basename(file_path))
if os.path.exists(old_file):
current_date = post.get("date")
old_date = frontmatter.load(old_file).get("date")
if current_date == old_date:
return False
return True

def sync_pic(file_path: str, output_dir: str) -> None:
"""copy pic to output dir"""
# find pic in markdown file
with open(file_path, "r", encoding="utf-8") as f:
markdown_body = f.read()
pic_str_list = re.findall(r"\!\[.*\]\((.*)\)", markdown_body)
for pic_str in pic_str_list:
print(f" find pic {pic_str}")
pic_file = os.path.join(os.path.dirname(file_path), pic_str)
if not os.path.exists(pic_file):
continue
# copy pic
output_pic_file = os.path.join(output_dir, "images", os.path.basename(pic_file))
print(f" copy {os.path.abspath(pic_file)} to {output_pic_file}")
shutil.copyfile(pic_file, output_pic_file)
return

def handler_file(root: str, file: str, output_dir: str) -> None:
"""处理单个 markdown 文件"""
file_path = os.path.join(root, file)
if not _need_sync(file_path, output_dir):
return
# copy file
output_file_path = os.path.join(output_dir, default_dir, file)
print(f"copy {file_path} to {output_file_path}")
shutil.copyfile(file_path, output_file_path)
# copy pic
sync_pic(file_path, output_dir)

def main(
markdown_path: str = r"E:\PycharmProjects\WG\note",
output_dir: str = r"E:\PycharmProjects\AngusWG\docs",
) -> None:
"""
遍历 note 文件夹 articles 文件夹下所有的 md 文件

并同步到另一边文件夹下的 articles 文件夹下
- sorce_note_dir: 笔记文件夹
- articles: 可以发布的文章文件夹
- a.md (article: true)
- b.md (article: true)
- c.md (article: false)
- images: 笔记图片文件夹
- a1.png
- a2.png
- c1.png
- target_note_dir: 笔记文件夹
- articles: 已经发布的博客文件夹
- a.md (article: true)
- b.md (article: true)
- images: 博客图片文件夹
- a1.png
- a2.png
"""
# walk directory
root = os.path.join(markdown_path, default_dir)
for file in os.listdir(root):
if file.endswith(".md"):
handler_file(root, file, output_dir)

if __name__ == "__main__":
main()
# handler_file(
# r"E:\PycharmProjects\WG\note\docs\创作",
# "笔记自动发布。md",
# r"E:\PycharmProjects\AngusWG\docs",
# )

博客项目生成 pr

name: SYNC NOTE
on:
push:
branches:
- dev_auto
jobs:
SYNC_NOTE:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: master
- run: ls
- name: Reset main branch
run: |
git fetch origin dev_auto:dev_auto
git reset --hard dev_auto
- name: Create Pull Request
uses: peter-evans/create-pull-request@v4
id: cpr
with:
commit-message: publish note to blog
title: sync note pull request
body: $(date +"%Y-%m-%dT%H:%M:%S%z")
branch: dev_auto
base: master

小坑:

报错 Branch 'X' no longer differs from base branch 'Y'

actions 好像将本地的分支提交一次,最开始的时候写错了, 导致反向 master 覆盖了 dev_auto 分支, 然后因为没有 git fetch ,认为无修改不生成 pr。 看 action 日志+看 issus 解决的。 action 的运行方式有点想当然了。

总结

最开始想用 tag: publish 去识别是否要发布,但是刷 attribute 的脚本不支持增加,支持覆盖, 想了想还是新弄个属性,反正人也看不到。

目前还有一个问题是,这个 action 是每次提交就会检测一遍,然后装 python 依赖的时候,其实挺慢的, 找了一下,并没有限制最小部署间隔的参数(有知道的小伙伴请告诉我)想想机器又不累,不要在乎这么多。

笔记阅读需 5 分钟

屁大点事写个帖子

pycharm 格式化 Ctrl+Shift+L, 每次写完(改完)顺手格式化一下, 非常的舒服。

最近开始接触开源项目, 很多用的 black 格式化工具, 还有 mypy 等等代码检查工具。

冲突点在于 pycharm 另起的一行的参数空 8 格, black 空四格。

在用 black 风格检查的代码的情况下, pycharm 的格式化显得不友好了。

最开始想直接 pycharm reformat 用上 black,但是看了看 jetbrain 的插件:

BlackConnect 要起服务端,而且快捷键不同 (Alt + Shift + B)

解决方案

提交时修改

后面还是妥协普通编写时用 pycharm reformat 提交时统一 black 格式化

需要的是把Continuation indent 改为4

后期再通过 git hook 格式化或者检查代码

更换 pycharm format 工具

step1 安装

windows 下 先 python 安装 black isort

pip install black isort -U pip install black==22.1 isort==5.10 -U # 安装指定版本

step2 工具位置

然后找到 black 和 isort 的命令位置

  • windows
    • where black
    • where isort
  • mac
    • which black
    • which isort

step3 pycharm 配置扩展工具

File -> Settings -> Tools -> External Tools

+号按钮 增加新的拓展工具

Name: Black
Description: Black is the uncompromising Python code formatter.
Program: <install_location_from_step_2>
# Program: d:/ProgramData/Miniconda3/Scripts/black.exe
Arguments: $FilePath$

Name: Isort
Description: Sort imports in current file
Program: <install_location_from_step_2>
# Program: d:/ProgramData/Miniconda3/Scripts/black.exe
Arguments: -e -m 4 -w 120 $FilePath$

step4 pycharm 配置快捷键

Settings -> Keymap -> External Tools -> External Tools

  • Black. 选择后输入 Ctrl+Alt+L 顶掉原来的快捷键
  • Isort. 同理,输入 Ctrl+Alt+O 顶掉原有的 import 格式化

配置完后 就可以使用 black 和 isort 格式化代码了。

pycharm 原有设置 (方便小伙伴还原)

拓展工具原有快捷键名称快捷键
BlackReformat CodeCtrl+Alt+L
IsortOptimize ImportsCtrl+Alt+O

关于 lint check

参考一下 fastapi

mypy fastapi
flake8 fastapi tests
black fastapi tests --check
isort fastapi tests docs_src scripts --check-only

或者用 python 插件 pre-commit-hooks 配置参考这个项目 simple_calculate_service

# cat .pre-commit-config.yaml
- repo: https://github.com/pre-commit/pre-commit-hooks
sha: v1.11.1
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-json
- id: flake8
exclude: migrations|.*\_local.py|manage.py|settings.py

参考 fastapi-crudrouter

  lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
- name: Run Black Code Formatter
uses: psf/black@stable
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r tests/dev.requirements.txt
- name: Check Typing with mypy
run: |
mypy fastapi_crudrouter
- name: Lint with flake8
run: |
flake8 fastapi_crudrouter

vscode 插件问题

报错:The Black Formatter server crashed 5 times in the last 3 minutes. The server will not be restarted. See the output for more

修改配置 其他不用改:

{
"black-formatter.path": [
"C:\\Users\\z7407\\AppData\\Roaming\\Python\\Python310\\Scripts\\black.exe"
]
}

Ctrl+Alt+L 不起作用

快捷键配置 看是否能搜索到

命令窗 搜索 Format Document with... 设置 black 为 Default

屁大点事阅读需 3 分钟