我有一个python项目,我使用pyinstaller在Linux上构建了一个可执行文件。 python还使用了python的 sh 模块。
运行单个可执行文件时,以下命令似乎不起作用:
getattr(sh, 'mount')
getattr(sh, 'ls')
虽然我检查正确设置的os.environ['PATH']
并执行以下工作:
sh.which('mount') -> /bin/mount
我理解sh
模块的行为与其他python包的行为不同,因为它动态导入命令。等。
是否会导致pyinstaller出现问题?
答案 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。