关于 python3 导入包的问题

2019-10-25 12:00:13 +08:00
 0clickjacking0

我安装了一个模块,名字叫 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

3235 次点击
所在节点    Python
13 条回复
Sylv
2019-10-25 12:06:46 +08:00
😂 哪有单独 import 一个类的实例方法?
lc1450
2019-10-25 12:09:40 +08:00
没这个必要吧,看了下,requests 大小不超过 500kb 看看其他模块
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
2019-10-25 12:12:54 +08:00
可以,用 pikle 序列化函数就好了,导入直接导入序列化的二进制。但能不能用就随缘了。
imn1
2019-10-25 12:17:39 +08:00
因为这个 get 方法实际还是依赖整个包的,你觉得就一个类
如果它不依赖,单独可执行,你把它 copy 出来放到工程目录下就够了

另外,打包 exe 很大,最主要是把 python 本身也要打包,不然怎么解析 py 脚本自运行?
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
2019-10-25 12:33:29 +08:00
对于文件大小问题:pyinstaller 可以自动调用 upx 压缩最后的二进制文件,看看你打包的时候有没有说 upx enabled
ungrown
2019-10-25 16:35:21 +08:00
@ClericPy
真的假的?
有没有链接,或者关键词?我想看看相关资料
ClericPy
2019-10-25 16:36:17 +08:00
@ungrown 你说的啥? 我怎么没看懂...
Vegetable
2019-10-25 16:43:56 +08:00
方向不对,如你所说,py 文件本身很小,之所以打包变大是因为他需要打包解释器。十几 mb 也并不大。哪怕你只引入了一个 get 方法没引入别的,也会在运行时报错,典型的例子就是打包 scrapy 程序的时候必须手动 import 框架本身会动态引入依赖,否则项目根本跑步起来。

我的记忆中,pyinstaller 只会分析静态的 import,所以我处理引入问题时往往都是在补而不是像你这样删。如果你真的很介意包的大小,建议你直接用 urllib
ungrown
2019-10-25 16:50:33 +08:00
@ClericPy “pyinstaller 打包的时候好像是整个 site-packages 的”
ClericPy
2019-10-25 16:52:23 +08:00
@ungrown stackoverflow 一搜一大片啊... 我以前在上面看的, 现在去找有点麻烦, 随手搜了个
https://zhuanlan.zhihu.com/p/76974787
也就是 pyinstaller 里为什么要给你个 exclude 参数, 因为好多库你不想要啊~
aaronhua
2019-10-25 22:02:13 +08:00
打包一个 hello world 都有 10M。因为它要打包很多底层的东西的。况且,用 pyinstaller 打包。12M,已经很小了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/612872

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX