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 · 3049 次点击
    这是一个创建于 1659 天前的主题,其中的信息可能已经有所发展或是发生改变。

    腾讯云最新优惠活动来了:云产品限时1折,云服务器低至88元/年 ,点击这里立即抢购:9i0i.cn/qcloud,更有2860元代金券免费领取,付款直接抵现金用,点击这里立即领取:9i0i.cn/qcloudquan

    (福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

    我安装了一个模块,名字叫 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   ·   实用小工具   ·   3096 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 257ms · UTC 12:57 · PVG 20:57 · LAX 05:57 · JFK 08:57
    Developed with CodeLauncher
    ? Do have faith in what you're doing.


    http://www.vxiaotou.com