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
LeeReamond
V2EX  ›  Python

奇技淫巧

  •  
  •   LeeReamond · 316 天前 · 3787 次点击
    这是一个创建于 316 天前的主题,其中的信息可能已经有所发展或是发生改变。

    起因是两个痛点:

    • IO 常用方法,比如读取和写入文件,每次都要写一长串,好烦
    • 调试代码时候偶尔会出现忘记把'w'模式改成'r'模式,导致数据被意外清空的情况
    with open('text.txt', 'w', encoding='utf-8') as f:
        f.write("Hello World!")
    with open('text.txt', 'r', encoding='utf-8') as f:
        text = f.read()
    

    由于编码基本上除了 utf-8 很少用别的,所以直接两句话写成函数,变成:

    from pipeit import Read, Write
    
    Write("text.txt", "Hello World!")
    text = Read("text.txt")
    

    好处除了少写几个字外,拆成 Read 和 Write 更不容易调错模式。 当然,这是幼儿园时候做的工作了,不值一提。

    但是事已至此还有一个痛点,就是在这种模式下需要使用序列化的话(这也是常用操作),逻辑顺序就不太对

    from pipeit import Read, Write
    import json 
    
    l = list(range(10))
    Write("l.json", json.dumps(l))  # 符合向 A 文件写入 B 的逻辑顺序
    ll = json.loads(Read("l.json")) # 书写顺序上,不是先“读”再“解”,感觉写起来很别扭
    

    py 做链式逻辑和函数式运算经常出现这种不太舒服的问题,不舒服这么长时间也一直忍着了。不过今天临睡前突然脑洞,既然函数式运算可以将习惯改成l = range(10) | Filter(lambda x:x^2) | Map(str) | list这种形式,读写能不能也进一步魔改一下,变成如下效果:

    json.dumps(list(range(10))) | Write("l.json")
    l = Read("l.json") | json.loads
    

    想了想,类似管道的写法用魔术方法重载可以很容易地实现,但是需要同时让 Read/Write 函数能向管道传递东西,又能直接读文件到字符串,这就需要再多费些力气了。于是又推迟睡眠时间 1 小时,罪过罪过,明天一定早睡。。。

    最后成品效果大概是这样:

    思路大概是用内建的 inspect 和 ast 模块实现抽象和反射,让Read()既是类也是函数,需要是类就是类,需要是函数就是函数。。。困了,代码还没整理上传到 pypi ,有时间再搞吧。

    没什么意义,有点回字的四种写法。但是一个语言能灵活至此,我玩得很开心就是。

    10 条回复    2024-03-16 23:04:21 +08:00
    nagisaushio
        1
    nagisaushio  
       316 天前 via Android
    iorilu
        2
    iorilu  
       316 天前   ❤️ 2
    读写文件可用 Path

    有 read_text , write_text 方法
    NoOneNoBody
        3
    NoOneNoBody  
       316 天前
    写了一堆闭包,就是为了防止这种错误,以及懒得记参数
    txtRead, txtWrite, txtAppend
    bytesRead, bytesWrite, bytesAppend
    jsonLoads, jsonDumps, jsonRead, jsonWrite
    pickleLoads, pickleDumps, pickleWrite
    csvLoad, csvDumps, csvRead, csvWrite
    ...
    yanyao233
        4
    yanyao233  
       315 天前 via Android
    我一般写项目先加这种工具类,记这些东西太麻烦了
    LeeReamond
        5
    LeeReamond  
    OP
       315 天前
    @nagisaushio v 站 py 区发库的很多都认识,他写他的我写我的

    @iorilu Path 字多麻烦,最麻烦的是 write_text 还要打 utf-8 ,我实在是不想再打 utf 横岗 8 这几个键了。

    @yanyao233 我现在基本就是工具类上 pypi ,换环境云端携带,习惯性先 from import *
    iorilu
        6
    iorilu  
       315 天前   ❤️ 2
    @LeeReamond 我不这么看

    我现在牢记, 优选使用标准库, 不随便造轮子

    代码, 可读性第一(这个可读性是指第一次看代码的人)
    LeeReamond
        7
    LeeReamond  
    OP
       315 天前   ❤️ 3
    @iorilu 如果感到快乐你就拍拍手
    zhanglintc
        8
    zhanglintc  
       287 天前
    等下

    json.dumps(list(range(10))) | Write("l.json")
    l = Read("l.json") | json.loads

    这里的 `|` 是什么,没见过 Python 里这个可以重载的啊?
    LeeReamond
        9
    LeeReamond  
    OP
       287 天前
    @zhanglintc 然而它确实可以重载摊手
    zhanglintc
        10
    zhanglintc  
       286 天前
    @LeeReamond #9 重载的是 `__or__` 呗?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2878 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 08:13 · PVG 16:13 · LAX 00:13 · JFK 03:13
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.