为什么 Python 3 的 tkinter 导入语法在 Python 2 中有效,但在 pyinstaller 中无效?

问题描述 投票:0回答:2

TL; DR: 标题的第一部分在下面的接受答案(我自己的)中简单回答。第二部分,关于

pyinstaller
,从来没有回答过。

我不建议你浪费时间阅读这个问题的其余部分和许多评论。


我正在通过 Anaconda 运行 Python 2.7,据我所知没有安装 Python 3。我对导入

tkinter
感到困惑。 Stack Overflow 上的其他几个问题表明,
tkinter
有单独的模块和略微不同的导入语法,具体取决于您运行的是 Python 2 还是 Python 3。但是,Python 3 语法有点 在 Python 2 中对我有用(请参阅下面代码中的注释)。给了什么?

import sys
print sys.version
# prints: 2.7.12 |Continuum Analytics, Inc.| (default, Jun 29 2016, 11:07:13) [MSC v.1500 64 bit (AMD64)]

# I hear these should not work in Python 2.  
# In reality, they work fine if run normally via the Python 2 interpreter.
# However, they do NOT work when I use pyinstaller to make an executable.
from tkinter import *
from tkinter import ttk, messagebox

# These work fine in Python 2, as they should, even if compiled into an exe.
from Tkinter import *
import ttk
import tkMessageBox

编辑:

回应Bryan Oakley的评论,

print sys.path
的结果是:

['C:\\Users\\...\\tkinter test program', 
'C:\\Miniconda\\python27.zip', 
'C:\\Miniconda\\DLLs', 
'C:\\Miniconda\\lib', 
'C:\\Miniconda\\lib\\plat-win', 
'C:\\Miniconda\\lib\\lib-tk', 
'C:\\Miniconda', 
'C:\\Miniconda\\lib\\site-packages', 
'C:\\Miniconda\\lib\\site-packages\\win32', 
'C:\\Miniconda\\lib\\site-packages\\win32\\lib', 
'C:\\Miniconda\\lib\\site-packages\\Pythonwin', 
'C:\\Miniconda\\lib\\site-packages\\setuptools-23.0.0-py2.7.egg']

针对 Sun Bear 的回答,这是我电脑上发生的事情:

C:\>python
Python 2.7.12 |Continuum Analytics, Inc.| (default, Jun 29 2016, 11:07:13) [MSC
v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
Anaconda is brought to you by Continuum Analytics.
Please check out: http://continuum.io/thanks and https://anaconda.org
>>> import tkinter
>>>

回应 Łukasz Rogalski 的评论:

>>> import Tkinter
>>> print Tkinter.__file__
C:\Miniconda\lib\lib-tk\Tkinter.pyc
>>> import tkinter
>>> print tkinter.__file__
C:\Miniconda\lib\site-packages\tkinter\__init__.pyc
>>>

针对Sun Bear的回答的评论中的讨论,这是

C:\Miniconda\lib\site-packages\tkinter\__init__.pyc
的内容,这解释了为什么即使我使用Python 2
import tkinter
也能工作:

from __future__ import absolute_import
import sys

if sys.version_info[0] < 3:
    from Tkinter import *
else:
    raise ImportError('This package should not be accessible on Python 3. '
                      'Either you are trying to run from the python-future src folder '
                      'or your installation of python-future is corrupted.')
python tkinter python-2.x pyinstaller
2个回答
0
投票

问题 1: 为什么 Python 2 解释器可以执行这段 Python 3 代码?

from tkinter import *
from tkinter import ttk, messagebox

答案:(根据我的问题更新和我/其他人的评论综合)使它起作用的是模块

python-future
。安装该模块会创建各种“包装器”文件,这些文件除了将 Python 3 元素重定向到它们的 Python 2 元素外什么都不做:
tkinter
->
Tkinter
tkinter.ttk
->
ttk
tkinter.messagebox
->
tkMessageBox
,等。这是
python-future
模块的关键目的之一。

例如,这里是

C:\Miniconda\lib\site-packages\tkinter\__init__.pyc

from __future__ import absolute_import
import sys

if sys.version_info[0] < 3:
    from Tkinter import *
else:
    raise ImportError('This package should not be accessible on Python 3. '
                      'Either you are trying to run from the python-future src folder '
                      'or your installation of python-future is corrupted.')

问题2:为什么同样的技巧似乎与模块不兼容

pyinstaller

答:不知道。这里没有人讨论过它,我也不想在 6 年后自己重温它。


-2
投票

tkinter
是适用于 Python 3 语法的 Tk 的 python 3 包装层。
Tkinter
是适用于 Python 2 语法的 Tk 的 python 2 包装层。

导入命令是一样的。但是您需要为您用来编写代码的 Python 版本类型导入正确的包装器。下面显示python 2只能导入

Tkinter
而不是
tkinter

$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import tkinter
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named tkinter
>>> import Tkinter
>>> 

更新: 如果 Miniconda 选择偏离主流做法并在幕后做一些事情来允许您所描述的内容,则由 Miniconda 自行决定。您的

print tkinter.__file__
命令显示您有
tkinter
print Tkinter.__file__
命令显示您有
Tkinter
。简而言之,Miniconda 预装了
Tkinter
tkinter
。您是否尝试过比较这两个文件以查看它们是否相同或不同?

© www.soinside.com 2019 - 2024. All rights reserved.