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

Python 引用私有模块的问题

  •  
  •   JCZ2MkKb5S8ZX9pq · 2020-11-27 14:46:32 +08:00 · 2612 次点击
    这是一个创建于 1492 天前的主题,其中的信息可能已经有所发展或是发生改变。

    自有工具

    • 有一些常用的命令和函数,做成了文件,比如 my_toolbox.py。实现的都是一些常用功能,比如

      • 各种时间格式相互转换
      • log 输出颜色
      • json 格式化打印
      • 系统语音、通知
      • 打印带框标题
      • 计时(含间隔)、计数
      • request 含重试和返回校验等
      • 总之就是一些常用函数和类,但是代码又有点长,不高兴每次都复制黏贴一遍的内容。
    • 平时调用就是 from my_tool import *。有些常用的导入也在这里面了,比如 os 、sys 、json 、re 等等。

    • 其它嘛还有一些使用频度低的,就单独拆开了,比如 excel 整理排错格式化后丢出 json,或者 df 通过 win32com 生成 excel 文件之类的。

    优点

    • 平时写点小东西比较快速,不用一个个去 import,或者复制代码。
    • 发现工具 bug 了,也可以统一修改,不用各处都去改动。

    缺点

    • 由于陆续地修改调整,可能部分函数没有向下兼容
    • 这个文件单独在外面,做 git 或者备份的时候,并不在项目内

    请问

    • 所以考虑要不要分一下版本,然后项目引用的时候标注下版本。有点像写 requirements,标注依赖版本。或者每个项目里都把依赖的私有工具都复制一份进去。

    • 如果是要分版本的话,实践中怎么处理比较好,想听听看大家的做法。

    15 条回复    2020-12-01 12:27:51 +08:00
    xiaojieluoff
        1
    xiaojieluoff  
       2020-11-27 14:55:40 +08:00 via Android
    这样一点都不 pythonic,Python 推荐的是按需导入,除非真的要因为导入的模块太多,可以合并到一个模块中。

    我觉得可以把 my_tool 模块整理下,规范命名,这样就可以在使用的时候按需导入,也能提高下代码的可读性。

    from tools import subtool
    no1xsyzy
        2
    no1xsyzy  
       2020-11-27 14:57:26 +08:00
    1. 用自己的名字发布到 pypi,按标准的包管理方式管理,精确控制版本,还能顺便 open source license (划去
    2. 做成 snippet 而不是引入
    JCZ2MkKb5S8ZX9pq
        3
    JCZ2MkKb5S8ZX9pq  
    OP
       2020-11-27 15:01:26 +08:00
    @no1xsyzy

    做成 snippet 有时候还是挺臃肿的,有些功能就是个小的类,也有个三十行上下。结果还是会变成在项目里嵌一个 toolbox 进去。
    JCZ2MkKb5S8ZX9pq
        4
    JCZ2MkKb5S8ZX9pq  
    OP
       2020-11-27 15:04:13 +08:00
    @xiaojieluoff

    其实已经一点点精简过了,剩下的都是比较常用的,不常用的的确都单独 from util.sub_tool import func_name 。

    但写小东西多,共享的一般还是都老老实实一个个导入通用的模块,然后单独复制一段代码。自己用的话就图快图方便了。

    就是想在这个基础上怎么再优化一下。
    JCZ2MkKb5S8ZX9pq
        5
    JCZ2MkKb5S8ZX9pq  
    OP
       2020-11-27 15:08:07 +08:00
    @xiaojieluoff 另外也试过 from my_tool import a,b,c,d,e
    结果一下子引用十几个…… 后来就偷懒直接 * 了
    在便利和规范好维护之间纠结
    no1xsyzy
        6
    no1xsyzy  
       2020-11-27 15:20:50 +08:00
    @JCZ2MkKb5S8ZX9pq 我的意思是,你这个 toolbox 可以拆成多个 snippet
    当然如果结构乱了还是整理下发 pypi,requirements 也就直接写 <my_name>_utils==1.2.3 了
    JCZ2MkKb5S8ZX9pq
        7
    JCZ2MkKb5S8ZX9pq  
    OP
       2020-11-27 15:23:37 +08:00
    @no1xsyzy 发 pypi 倒是没试过,稍后我去看看怎么搞的。
    CzaOrz
        8
    CzaOrz  
       2020-11-27 17:56:00 +08:00
    我也有一个类似的工具包,大而杂,到最后光加载这一个工具包就会明显卡顿。。。(包含 Scrapy 、Selenium 、Log 、Django 、Tarnado...)
    所以还是拆开吧,可以把自己喜欢的上传到 pypi~
    CzaOrz
        9
    CzaOrz  
       2020-11-27 17:56:36 +08:00
    log 输出颜色
    json 格式化打印
    JCZ2MkKb5S8ZX9pq
        10
    JCZ2MkKb5S8ZX9pq  
    OP
       2020-11-27 19:09:43 +08:00
    @CzaOrz 你这个听上去就很大,我的还没那么重。
    基本即使些经常用到的 os/sys/time/json 这类的小东西,基本每个文件都会用到。
    有些比如 pandas/PIL/numpy 我也是单独都拆出来了,并不是每个文件都会用到。

    另外有些项目基本成型了固定了,我也就单独把用到的都拆包放个备份了。
    就是写一半的,和有些小玩意儿,随后写随手引用,但日后再调发现跑不通了。
    imn1
        11
    imn1  
       2020-11-27 19:10:02 +08:00
    前置,不要扔到一个 py 里面,最好不同功能、不同 import 分开,放在一个目录(可以有子目录)

    你了解一下 .pth 文件,放到 site-packages,指向上述这个目录就行,然后就可以当三方包用了
    至于打包,或编译,另外再处理就是了,只是路径问题

    向下兼容嘛,如果是放到 site-packages,自然就能做到不同 version 指向不同目录

    我自己有几十个 py,里面过半是闭包或装饰器,自制语法糖等等,就是预定一些格式,不用每次写都加一段格式转换的代码,例如要处理日文,我就预设 shift-jis,不用每个 encode/decode (还有其他函数)都要带上 encoding=sjis 参数了
    又例如自制表达式:
    lst = LIST(a) - b, 相当于 lst: list = [x for x in list(a) if x not in b]
    s = STR(a) - b 相当于 s: str = str(a).replace(b, '')
    😄

    后置,我的代码不交给别人的用的,所以乱写没关系,不崩不算错就行,别人不宜模仿,🐶
    Trim21
        12
    Trim21  
       2020-11-27 19:14:18 +08:00 via Android
    os 之类的模块不应该这么引入。

    想分版本可以发到 pypi
    bbbb
        13
    bbbb  
       2020-11-28 21:57:35 +08:00 via iPhone
    关注,学习一下
    abersheeran
        14
    abersheeran  
       2020-11-29 10:49:51 +08:00
    import * 记得要写 __all__

    个人觉得,最好还是按需复制粘贴好一点。你不能保证你的每个功能都是能适应任何场景的,复制粘贴就可以按需修改。

    真想版本控制,那就推到 pypi 上。
    luxiaoer
        15
    luxiaoer  
       2020-12-01 12:27:51 +08:00
    每个做项目遇到的问题吧。
    个人看法
    单独 git
    把功能都继承到自定义的基础类里面去,类初始化的时候传入版本号,版本号默认一个值
    功能函数 类中判断功能函数实现向下兼容
    对于重构的功能就直接继承后重新写好了
    类似 sdk 的写法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2493 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:59 · PVG 12:59 · LAX 20:59 · JFK 23:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.