为什么Python 3的tkinter导入语法在Python 2中可以工作,但在pyinstaller中不行?

qv7cva1a  于 2023-04-28  发布在  Python
关注(0)|答案(2)|浏览(121)

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

我不建议你浪费时间阅读这个问题的其余部分和许多评论。
我正在运行Python 2。7通过Anaconda,据我所知没有安装Python 3。我对导入tkinter感到困惑。Stack Overflow上的其他几个问题表明,tkinter有单独的模块和略有不同的导入语法,这取决于你是运行Python 2还是Python 3。然而,Python 3语法 sort of 在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奥克利评论的回应,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
>>>

关于Vukasz 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.')
kq4fsx7k

kq4fsx7k1#

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

from tkinter import *
from tkinter import ttk, messagebox

答案:(根据我的问题更新和我/其他人的评论合并)使其工作的是模块python-future。安装该模块会创建各种“ Package 器”文件,这些文件除了将Python 3元素重定向到Python 2元素之外什么都不做:tkinter -〉Tkintertkinter.ttk -〉ttktkinter.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年后重温它。

lsmd5eda

lsmd5eda2#

tkinter是适合Python 3语法的Tk的Python 3 Package 层。
Tkinter是适合Python 2语法的Tk的Python 2 Package 层。
import命令是一样的。但是您需要为编写代码所使用的Python版本类型导入正确的 Package 器。下图显示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__命令显示您有tkinterprint Tkinter.__file__命令显示您有Tkinter。简而言之,Miniconda预装了Tkintertkinter。你试过比较这两个文件看它们是相同还是不同吗?

相关问题