# Python在Windows上的常见问题

目录

- Python在Windows上的常见问题

  - 我怎样在Windows下运行一个Python程序？

  - 我怎么让 Python 脚本可执行？

  - 为什么有时候 Python 程序会启动缓慢？

  - 我怎样使用Python脚本制作可执行文件？

  - `*.pyd` 文件和DLL文件相同吗？

  - 我怎样将Python嵌入一个Windows程序？

  - 如何让编辑器不要在我的 Python 源代码中插入 tab ？

  - 如何在不阻塞的情况下检查按键？

  - How do I emulate os.kill() in Windows?

  - How do I extract the downloaded documentation on Windows?

## 我怎样在Windows下运行一个Python程序？

这不一定是一个简单的问题。如果你已经熟悉在Windows的命令行中运行程序的方法，一切都显而易见；不然的话，你也许需要额外获得些许指导。

Unless you use some sort of integrated development environment, you will end up typing Windows commands into what is variously referred to as a “DOS window” or “Command prompt window”. Usually you can create such a window from your Start menu; under Windows 7 the menu selection is Start ‣ Programs ‣ Accessories ‣ Command Prompt. You should be able to recognize when you have started such a window because you will see a Windows “command prompt”, which usually looks like this:

    C:\>

The letter may be different, and there might be other things after it, so you might just as easily see something like:

    D:\YourName\Projects\Python>

出现的内容具体取决与你的电脑如何设置和最近用它做的事。 当你启动了这样一个窗口后，就可以开始运行Python程序了。

Python 脚本需要被另外一个叫做 Python 解释器 的程序来处理。 解释器读取脚本，把它编译成字节码，然后执行字节码来运行你的程序。 所以怎样安排解释器来处理你的 Python 脚本呢？

First, you need to make sure that your command window recognises the word “python” as an instruction to start the interpreter. If you have opened a command window, you should try entering the command `python` and hitting return.:

    C:\Users\YourName> python

You should then see something like:

    Python 2.7.3 (default, Apr 10 2012, 22.71:26) [MSC v.1500 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>>

You have started the interpreter in “interactive mode”. That means you can enter Python statements or expressions interactively and have them executed or evaluated while you wait. This is one of Python’s strongest features. Check it by entering a few expressions of your choice and seeing the results:

    >>> print "Hello"
    Hello
    >>> "Hello" * 3
    'HelloHelloHello'

Many people use the interactive mode as a convenient yet highly programmable calculator. When you want to end your interactive Python session, hold the `Ctrl` key down while you enter a `Z`, then hit the “`Enter`” key to get back to your Windows command prompt.

You may also find that you have a Start-menu entry such as Start ‣ Programs ‣ Python 2.7 ‣ Python (command line) that results in you seeing the `>>>` prompt in a new window. If so, the window will disappear after you enter the `Ctrl-Z` character; Windows is running a single “python” command in the window, and closes it when you terminate the interpreter.

If the `python` command, instead of displaying the interpreter prompt `>>>`, gives you a message like:

    'python' is not recognized as an internal or external command, operable program or batch file.

or:

    Bad command or filename

then you need to make sure that your computer knows where to find the Python interpreter. To do this you will have to modify a setting called PATH, which is a list of directories where Windows will look for programs.

You should arrange for Python’s installation directory to be added to the PATH of every command window as it starts. If you installed Python fairly recently then the command

    dir C:\py*

will probably tell you where it is installed; the usual location is something like `C:\Python27`. Otherwise you will be reduced to a search of your whole disk … use Tools ‣ Find or hit the Search button and look for “python.exe”. Supposing you discover that Python is installed in the `C:\Python27` directory (the default at the time of writing), you should make sure that entering the command

    c:\Python27\python

starts up the interpreter as above (and don’t forget you’ll need a “`Ctrl-Z`” and an “`Enter`” to get out of it). Once you have verified the directory, you can add it to the system path to make it easier to start Python by just running the `python` command. This is currently an option in the installer as of CPython 2.7.

More information about environment variables can be found on the Using Python on Windows page.

## 我怎么让 Python 脚本可执行？

在Windows上，标准Python安装程序已将.py扩展名与文件类型(Python.File) 相关联，并为该文件类型提供运行解释器的打开命令(`D:\Program Files\Python\python.exe "%1" %*`) 。 这足以使脚本在命令提示符下作为 ‘foo.py’ 命令被执行。 如果希望通过简单地键入“foo”而无需输入文件扩展名来执行脚本，则需要将.py添加到PATHEXT环境变量中。

## 为什么有时候 Python 程序会启动缓慢？

通常，Python 在 Windows 上启动得很快，但偶尔会有错误报告说 Python 突然需要很长时间才能启动。更令人费解的是，在其他配置相同的 Windows 系统上，Python 却可以工作得很好。

该问题可能是由于计算机上的杀毒软件配置错误造成的。当将病毒扫描配置为监视文件系统中所有读取行为时，一些杀毒扫描程序会导致两个数量级的启动开销。请检查你系统安装的杀毒扫描程序的配置，确保两台机它们是同样的配置。已知的， McAfee 杀毒软件在将它设置为扫描所有文件系统访问时，会产生这个问题。

## 我怎样使用Python脚本制作可执行文件？

See http://www.py2exe.org/ for a distutils extension that allows you to create console and GUI executables from Python code.

## `*.pyd` 文件和DLL文件相同吗？

Yes, .pyd files are dll’s, but there are a few differences. If you have a DLL named `foo.pyd`, then it must have a function `initfoo()`. You can then write Python “import foo”, and Python will search for foo.pyd (as well as foo.py, foo.pyc) and if it finds it, will attempt to call `initfoo()` to initialize it. You do not link your .exe with foo.lib, as that would cause Windows to require the DLL to be present.

请注意， foo.pyd 的搜索路径是 PYTHONPATH ，与 Windows 用于搜索 foo.dll 的路径不同。此外， foo.pyd 不需要存在来运行你的程序，而如果你将程序与 dll 链接，则需要 dll 。 当然，如果你想 `import foo` ，则需要 foo.pyd 。在 DLL 中，链接在源代码中用 `__declspec(dllexport)` 声明。 在 .pyd 中，链接在可用函数列表中定义。

## 我怎样将Python嵌入一个Windows程序？

在 Windows 应用程序中嵌入 Python 解释器可以总结如下：

1. Do _not_ build Python into your .exe file directly. On Windows, Python must be a DLL to handle importing modules that are themselves DLL’s. (This is the first key undocumented fact.) Instead, link to `pythonNN.dll`; it is typically installed in `C:\Windows\System`. NN is the Python version, a number such as “27” for Python 2.7.

   你可以通过两种不同的方式链接到 Python 。加载时链接意味着链接到 `pythonNN.lib` ，而运行时链接意味着链接 `pythonNN.dll` 。（一般说明： `python NN.lib` 是所谓的“import lib”，对应于 `pythonNN.dll` 。它只定义了链接器的符号。）

   运行时链接极大地简化了链接选项，一切都在运行时发生。你的代码必须使用 Windows 的 `LoadLibraryEx()` 程序加载 `pythonNN.dll` 。代码还必须使用使用 Windows 的 `GetProcAddress()` 例程获得的指针访问 `pythonNN.dll` 中程序和数据（即 Python 的 C API ）。宏可以使这些指针对任何调用 Python C API 中的例程的 C 代码都是透明的。

   Borland 提示：首先使用 Coff2Omf.exe 将 `pythonNN.lib` 转换为 OMF 格式。

2. 如果你使用 SWIG ，很容易创建一个 Python “扩展模块”，它将使应用程序的数据和方法可供 Python 使用。SWIG将为你处理所有蹩脚的细节。结果是你将链接到 .exe 文件 中 的C代码 (!) 你不必创建 DLL 文件，这也简化了链接。

3. SWIG 将创建一个 init 函数（一个 C 函数），其名称取决于扩展模块的名称。例如，如果模块的名称是 leo ，则 init 函数将被称为 initleo() 。 如果您使用 SWIG 阴影类，则 init 函数将被称为 initleoc() 。这初始化了一个由阴影类使用的隐藏辅助类。

   你可以将步骤 2 中的 C 代码链接到 .exe 文件的原因是调用初始化函数等同于将模块导入 Python ！ （这是第二个关键的未记载事实。）

4. 简而言之，你可以用以下代码使用扩展模块初始化 Python 解释器。

       #include "python.h"
       ...
       Py_Initialize();  // Initialize Python.
       initmyAppc();  // Initialize (import) the helper class.
       PyRun_SimpleString("import myApp");  // Import the shadow class.

5. Python C API 存在两个问题，如果你使用除 MSVC 之外的编译器用于构建 python.dll ，这将会变得明显。

   问题1：采用 FILE* 参数的所谓“极高级”函数在多编译器环境中不起作用，因为每个编译器的FILE结构体概念都不同。从实现的角度来看，这些是非常 _低_ 级的功能。

   问题2：在为void函数生成包装器时，SWIG会生成以下代码：

       Py_INCREF(Py_None);
       _resultobj = Py_None;
       return _resultobj;

   Py_None 是一个宏，它扩展为对 pythonNN.dll 中名为 _Py_NoneStruct 的复杂数据结构的引用。同样，此代码将在多编译器环境中失败。将此类代码替换为：

       return Py_BuildValue("");

   有可能使用 SWIG 的 `%typemap` 命令自动进行更改，但我无法使其工作（我是一个完全的SWIG新手）。

6. 使用 Python shell 脚本从 Windows 应用程序内部建立 Python 解释器窗口并不是一个好主意；生成的窗口将独立于应用程序的窗口系统。相反，你（或 wxPythonWindow 类）应该创建一个“本机”解释器窗口。将该窗口连接到Python解释器很容易。你可以将 Python的 i/o 重定向到支持读写的 _任意_ 对象，因此你只需要一个包含 read() 和 write() 方法的 Python 对象（在扩展模块中定义）。

## 如何让编辑器不要在我的 Python 源代码中插入 tab ？

本 FAQ 不建议使用制表符， Python 样式指南 PEP 8 ，为发行的 Python 代码推荐 4 个空格；这也是 Emacs python-mode 默认值。

在任何编辑器下，混合制表符和空格都是一个坏主意。 MSVC 在这方面没有什么不同，并且很容易配置为使用空格： 点击 Tools ‣ Options ‣ Tabs，对于文件类型“Default”，设置“Tab size”和“Indent size”为 4 ，并选择“插入空格”单选按钮。

If you suspect mixed tabs and spaces are causing problems in leading whitespace, run Python with the `-t` switch or run the `tabnanny` module to check a directory tree in batch mode.

## 如何在不阻塞的情况下检查按键？

使用 msvcrt 模块。 是标准的 Windows 特定扩展模块。它定义了一个函数 `kbhit()` 来检查是否存在键盘命中，而 `getch()` 来获取一个字符而不回显它。

## How do I emulate os.kill() in Windows?

Prior to Python 2.7 and 3.2, to terminate a process, you can use `ctypes`:

    import ctypes

    def kill(pid):
        """kill function for Win32"""
        kernel32 = ctypes.windll.kernel32
        handle = kernel32.OpenProcess(1, 0, pid)
        return (0 != kernel32.TerminateProcess(handle, 0))

In 2.7 and 3.2, `os.kill()` is implemented similar to the above function, with the additional feature of being able to send `Ctrl+C` and `Ctrl+Break` to console subprocesses which are designed to handle those signals. See `os.kill()` for further details.

## How do I extract the downloaded documentation on Windows?

Sometimes, when you download the documentation package to a Windows machine using a web browser, the file extension of the saved file ends up being .EXE. This is a mistake; the extension should be .TGZ.

Simply rename the downloaded file to have the .TGZ extension, and WinZip will be able to handle it. (If your copy of WinZip doesn’t, get a newer one from https://www.winzip.com.)