pyinstaller和python的sh模块

时间:2014-07-22 15:47:13

标签: python linux pyinstaller

我有一个python项目,我使用pyinstaller在Linux上构建了一个可执行文件。 python还使用了python的 sh 模块。

运行单个可执行文件时,以下命令似乎不起作用:

getattr(sh, 'mount')
getattr(sh, 'ls')

虽然我检查正确设置的os.environ['PATH']并执行以下工作:

sh.which('mount') -> /bin/mount

我理解sh模块的行为与其他python包的行为不同,因为它动态导入命令。等。

是否会导致pyinstaller出现问题?

1 个答案:

答案 0 :(得分:1)

更准确地重现您的问题:

cat > test.py << EOF
import sh
ls = getattr(sh, 'ls')
print(ls('-d', '/tmp'))
EOF

通常情况下,这很好用:

$ python test.py
/tmp

但是使用PyInstaller,会引发AttributeError:

$ ./pyinstaller test.py
$ ./dist/test/test
Traceback (most recent call last):
  File "<string>", line 3, in <module>
AttributeError: 'module' object has no attribute 'ls'

你是对的, PyInstaller 有一个自定义模块加载器,它与 sh 模块不能很好地相互作用。简言之。

这可以通过复制相同的&#34; Magic&#34;来解决。那个 sh.Environment .__ getitem __ 方法执行。

我们可以按如下方式修改test.py:

import sh

ls = sh.Command._create('ls')
print(ls('-d', '/tmp'))

这很好。

$ ./pyinstaller test.py
$ ./dist/test/test
/tmp

sh.py 使用 sh.SelfWrapper 的实例重载 sys.modules [__ name __] 。这是与 PyInstaller 冲突的地方,其自定义模块导入器不会将sys.modules评估为标准python。