首页 > 解决方案 > Python 导入和文件嵌入

问题描述

我正在处理一个导入多个包的项目,当脚本运行时,我加载了一个神经网络模型。

我想知道以下是否可以实现:

  1. 如果我在另一个 python 环境中运行脚本,我需要安装所有导入的包。有可能避免这种情况吗?这将消除第一次安装所有软件包的需要。
  2. 是否可以将神经网络 .pb 嵌入代码中?请记住,它重 80mb,因此十六进制转储不起作用(带有转储的文本文件重 700mb)

这个想法是让 1 .py 包含所有必要的内容。可能吗?

谢谢!

标签: pythonpython-3.x

解决方案


如果我在另一个 python 环境中运行脚本,我需要安装所有导入的包。有可能避免这种情况吗?

好吧,不是真的,而是有点(TL;DR不,但取决于你的意思)。它实际上只是归结为环境的限制。在某个地方,某个地方,您需要可以从磁盘中获取它们的软件包——就这么简单。它们必须可用且可定位

可用,我的意思是可以通过文件系统访问。通过可定位,我的意思是必须有你正在寻找的地方。系统安装会将其放置在可以访问的地方,并且可以可靠地用作安装和查找包的地方。这是您的虚拟环境责任的一部分。唯一的区别是,您的虚拟环境将您与系统 Python 的包分开。

这样做的好处是直截了当的:我可以创建一个使用 package 的虚拟环境slamjam==1.2.3,其中1.2.3是 package 的特定版本slamjam并且还可以运行一个使用的程序,slamjam==1.7.9而不会在我的全局环境中引起冲突。

所以这就是为什么我给出“有点”的感觉:如果你的用户已经在你的系统上安装了一个包,那么你的用户不需要安装任何东西。如果该软件包已全局安装在他们的系统上,则他们不需要该软件包的虚拟环境。同样,如果它在另一个虚拟环境中,他们也不需要一个新的,尽管将您的项目依赖关系与一个分离是一个好主意。

是否可以将神经网络 .pb 嵌入代码中?请记住,它重 80mb,因此十六进制转储不起作用(带有转储的文本文件重 700mb)

所以,是的,实际上这是非常可行的。问题是,这取决于你的意思。

如您所知,文件的十六进制转储会占用大量空间。这是非常真实的。但是您似乎在谈论原始十六进制,每个字节至少需要 2 个字节。hexdump然后,如果您使用类似、yada、yada yada 之类的工具,您可能会因此倾倒额外的信息。

故事的道德,你这样做会浪费很多空间。所以我会给你几个选项,你可以选择一个或多个。

  1. 如果可能的话,压缩你的数据,甚至更多。

我没有使用过 TensorFlow 数据,但在快速阅读之后,它似乎使用了 ProtoBufs 压缩,而且它可能已经非常压缩了。好吧,不管怎样,去看看你能不能从水果里榨出更多的汁液。

  1. 获取二进制数据,并将其转储为不同的编码(提示,提示:base64!)

看看当我们将某些东西转换为十六进制时会发生什么......

>>> binary_data=b'this is a readable string, but really it just boils down to binary information. i can be expressed in a more efficient way than a binary string or hex, however'
>>> hex_data = binary_data.hex()
>>> print(hex_data)
746869732069732061207265616461626c6520737472696e672c20627574207265616c6c79206974206a75737420626f696c7320646f776e20746f2062696e61727920696e666f726d6174696f6e2e20692063616e2062652065787072657373656420696e2061206d6f726520656666696369656e7420776179207468616e20612062696e61727920737472696e67206f72206865782c20686f7765766572
>>> print(len(hex_data))
318

318 个字符?我们可以做得更好。

>>> import base64
>>> hex_data = binary_data.hex()
>>> import base64
>>> b64_data = base64.b64encode(binary_data)
>>> print(b64_data)
b'dGhpcyBpcyBhIHJlYWRhYmxlIHN0cmluZywgYnV0IHJlYWxseSBpdCBqdXN0IGJvaWxzIGRvd24gdG8gYmluYXJ5IGluZm9ybWF0aW9uLiBpIGNhbiBiZSBleHByZXNzZWQgaW4gYSBtb3JlIGVmZmljaWVudCB3YXkgdGhhbiBhIGJpbmFyeSBzdHJpbmcgb3IgaGV4LCBob3dldmVy'
>>> print(len(b64_data))
212

您现在已将数据缩小了 33%!

  1. 将非 Python 文件打包到您的.whl发行版中。是的,完全可行。我以前做过吗?不,从来不需要。我会吗?是的。我对如何做有很好的建议吗?不,但我有一个链接给你,这是完全可行的。

  2. 您可以从应用程序中下载文件,并且只提供 URL。快速简单的东西,比如

import wget

file_contents_in_memory = wget.download('some.site.com/a_file`)

是的,当然还有其他库,比如requests做类似的事情,但例如,我选择wget因为它也有一个简单的界面,并且始终是一个选项。

这个想法是让 1 .py 包含所有必要的内容。可能吗?

嗯,文件,是的。对于你要问的——一个.py没有其他东西可以安装你的包的文件?如果你真的想一个接一个地复制和粘贴一个库,并将所有数据复制到一个没有人下载的大文件中,我相信有办法。

让我们看一下您所要求的一种更受支持的方法:一个whl文件是一个文件,它可以有一个您需要安装的包的内部列表.whl,它将为您处理所有事情(安装、解包等)。我会朝那个方向看。

无论如何,我知道很多信息,但有一些关于为什么你可以或不能做某事的逻辑。希望对您有所帮助,并祝您好运。


推荐阅读