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
0clickjacking0
V2EX  ›  Python

关于 python3 导入包的问题

  •  
  •   0clickjacking0 · 2019-10-25 12:00:13 +08:00 · 3204 次点击
    这是一个创建于 1849 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我安装了一个模块,名字叫 requests,在这个模块下有一个叫sessions.py的文件,这个文件里面有一个类,叫做Session的类,Session类中有一个get方法,我该如何 import 这个方法呢,因为在api.py中也有一个get方法,貌似是函数同名类,所以我不知道该如何调用,我想使用from ... import ...的方法来实现,至于为什么要用这种方法,是因为我想把该文件打包成 exe,如果单纯的使用from requests import Session是可以成功的,但是一个 10kb 的文件打包出来有 12MB,所以我想尽可能的压缩

    这里是 requests 的目录结构,各位大佬有什么点子吗

    ├── __init__.py
    ├── __pycache__
    │   ├── __init__.cpython-37.pyc
    │   ├── __version__.cpython-37.pyc
    │   ├── _internal_utils.cpython-37.pyc
    │   ├── adapters.cpython-37.pyc
    │   ├── api.cpython-37.pyc
    │   ├── auth.cpython-37.pyc
    │   ├── certs.cpython-37.pyc
    │   ├── compat.cpython-37.pyc
    │   ├── cookies.cpython-37.pyc
    │   ├── exceptions.cpython-37.pyc
    │   ├── help.cpython-37.pyc
    │   ├── hooks.cpython-37.pyc
    │   ├── models.cpython-37.pyc
    │   ├── packages.cpython-37.pyc
    │   ├── sessions.cpython-37.pyc
    │   ├── status_codes.cpython-37.pyc
    │   ├── structures.cpython-37.pyc
    │   └── utils.cpython-37.pyc
    ├── __version__.py
    ├── _internal_utils.py
    ├── adapters.py
    ├── api.py
    ├── auth.py
    ├── certs.py
    ├── compat.py
    ├── cookies.py
    ├── exceptions.py
    ├── help.py
    ├── hooks.py
    ├── models.py
    ├── packages.py
    ├── sessions.py
    ├── status_codes.py
    ├── structures.py
    └── utils.py
    
    
    13 条回复    2019-10-25 22:02:13 +08:00
    Sylv
        1
    Sylv  
       2019-10-25 12:06:46 +08:00
    😂 哪有单独 import 一个类的实例方法?
    lc1450
        2
    lc1450  
       2019-10-25 12:09:40 +08:00
    没这个必要吧,看了下,requests 大小不超过 500kb 看看其他模块
    ClericPy
        3
    ClericPy  
       2019-10-25 12:11:56 +08:00
    理论上讲还真可以做到... 但是这是个实例方法啊,
    from requests import get
    print(get("http://python.org").text[:10])
    在包顶他们有 get 方法, 就是默认实例化了一个 Session

    然后提醒一句, 减少打包 exe 大小的正确思路是使用虚拟环境, 而不是想这种路子, requests 的包结构虽然还算清晰, 但是里面各种引用会让你就算不导入某些包, 也会在 init 的时候带上一些, 最多省点内存, pyinstaller 打包的时候好像是整个 site-packages 的
    BingoXuan
        4
    BingoXuan  
       2019-10-25 12:12:54 +08:00
    可以,用 pikle 序列化函数就好了,导入直接导入序列化的二进制。但能不能用就随缘了。
    imn1
        5
    imn1  
       2019-10-25 12:17:39 +08:00
    因为这个 get 方法实际还是依赖整个包的,你觉得就一个类
    如果它不依赖,单独可执行,你把它 copy 出来放到工程目录下就够了

    另外,打包 exe 很大,最主要是把 python 本身也要打包,不然怎么解析 py 脚本自运行?
    hakono
        6
    hakono  
       2019-10-25 12:26:11 +08:00
    这是不可能的,
    api.py 中的 get 方法你看看具体定义:

    ```
    from . import sessions

    def get(url, params=None, **kwargs):
    return request('get', url, params=params, **kwargs)
    ```
    也就是说,这个 get 方法实际上调用的依旧还是 session.py 中 的 get()
    你以为只导入 get() 可以节省空间,但问题是这个 get() 是属于 Session 类,get()方法是和 Session 类中各种方法关联的,要用的话必须完整导入 Session 类,然后 Session 类又用到其他类,也用到了很多关联的系统库,比如这是开头导入的内置库
    ```
    import os
    import sys
    import time
    from datetime import timedelta
    ```

    你要正常运行 request 就必须要导入这些库,然后 requests 其他类中也还导入了一堆系统内置库,用到了的话也必须一并导入到 exe 中,最后 exe 中还得内嵌一个微型的 python 执行环境
    也就是说你要正常用 requests,这些全都需要
    Trim21
        7
    Trim21  
       2019-10-25 12:33:29 +08:00 via Android
    对于文件大小问题:pyinstaller 可以自动调用 upx 压缩最后的二进制文件,看看你打包的时候有没有说 upx enabled
    ungrown
        8
    ungrown  
       2019-10-25 16:35:21 +08:00
    @ClericPy
    真的假的?
    有没有链接,或者关键词?我想看看相关资料
    ClericPy
        9
    ClericPy  
       2019-10-25 16:36:17 +08:00
    @ungrown 你说的啥? 我怎么没看懂...
    Vegetable
        10
    Vegetable  
       2019-10-25 16:43:56 +08:00
    方向不对,如你所说,py 文件本身很小,之所以打包变大是因为他需要打包解释器。十几 mb 也并不大。哪怕你只引入了一个 get 方法没引入别的,也会在运行时报错,典型的例子就是打包 scrapy 程序的时候必须手动 import 框架本身会动态引入依赖,否则项目根本跑步起来。

    我的记忆中,pyinstaller 只会分析静态的 import,所以我处理引入问题时往往都是在补而不是像你这样删。如果你真的很介意包的大小,建议你直接用 urllib
    ungrown
        11
    ungrown  
       2019-10-25 16:50:33 +08:00
    @ClericPy “pyinstaller 打包的时候好像是整个 site-packages 的”
    ClericPy
        12
    ClericPy  
       2019-10-25 16:52:23 +08:00
    @ungrown stackoverflow 一搜一大片啊... 我以前在上面看的, 现在去找有点麻烦, 随手搜了个
    https://zhuanlan.zhihu.com/p/76974787
    也就是 pyinstaller 里为什么要给你个 exclude 参数, 因为好多库你不想要啊~
    aaronhua
        13
    aaronhua  
       2019-10-25 22:02:13 +08:00
    打包一个 hello world 都有 10M。因为它要打包很多底层的东西的。况且,用 pyinstaller 打包。12M,已经很小了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2903 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 81ms · UTC 07:34 · PVG 15:34 · LAX 23:34 · JFK 02:34
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.