将用 Python 3.6 编写的 .py 文件转换为 .exe 的最佳方法?

Best way to convert a .py file written in Python 3.6 to an .exe?

我有一个 用 Python 3.6 编写的程序,我想将它转换为 .exe,这样我就可以在没有Python 或我在代码中使用的任何模块的要求。 我见过的大多数方法都不支持 Python 3.6,这就是我在这里提问的原因。 我试过使用 cx_Freeze,但是当我 运行 创建的 .exe 我得到 ImportError: cannot import name 'idnadata',所以我想知道将 Python 3.6 文件转换为 .exe 的最佳方法是什么。

我要转换的程序:

import os
import time
import sys
import getpass
import mmap
import imp
from contextlib import contextmanager


my_file = "Text To Speech.mp3"
username = getpass.getuser()


@contextmanager
def suppress_output():

    with open(os.devnull, "w") as devnull:
        old_stdout = sys.stdout
        sys.stdout = devnull
        try:  
            yield
        finally:
            sys.stdout = old_stdout


def check_and_remove_file():

    active = pygame.mixer.get_init()
    if active != None:
        pygame.mixer.music.stop()
        pygame.mixer.quit()
        pygame.quit()
    if os.path.isfile(my_file):
        os.remove(my_file)


def wait_for_it(audio_length, greater_than, less_than, time_to_wait):

    if (audio_length) >= (greater_than) and (audio_length) < (less_than):
        time.sleep((audio_length) + (time_to_wait))


def exiting():

    check_and_remove_file()
    print("\nGoodbye!")
    sys.exit()


def input_for_tts(message):

    try:

        tts = gTTS(text = input(message))
        tts.save('Text To Speech.mp3')
        with open(my_file) as f:
            m = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)
        audio = MP3(my_file)
        audio_length = audio.info.length
        try:
            pygame.mixer.init()
        except pygame.error:
            print("\nSorry, no audio device was detected. The code cannot complete.")
            exiting()   
        pygame.mixer.music.load(m)
        pygame.mixer.music.play()
        wait_for_it(audio_length, 0, 15, 1)
        wait_for_it(audio_length, 15, 30, 2)
        wait_for_it(audio_length, 30, 45, 3)
        wait_for_it(audio_length, 45, 60, 4)
        wait_for_it(audio_length, 60, 75, 5)
        wait_for_it(audio_length, 75, 90, 6)
        wait_for_it(audio_length, 90, 105, 7)
        wait_for_it(audio_length, 105, 120, 8)
        wait_for_it(audio_length, 120, 135, 9)
        wait_for_it(audio_length, 135, 150, 10)
        wait_for_it(audio_length, 150, 165, 11)
        wait_for_it(audio_length, 165, 180, 12)
        if audio_length >= 180:
            time.sleep((audio_length) + 15)
        try:
            m.close()
            check_and_remove_file()
        except PermissionError:
            imp.reload(pygame)
            check_and_remove_file()

    except KeyboardInterrupt:

        exiting()


import pygame
from pygame.locals import *
from gtts import gTTS
from mutagen.mp3 import MP3


check_and_remove_file()


input_for_tts("Hello there " + username + ". This program is\nused to output the user's input as speech.\nPlease input something for the program to say: ")


while True:

    try:

        answer = input("\nDo you want to repeat? ").strip().lower()
        if answer in ["n", "no", "nah", "nay", "course not", "don't", "dont", "not"] or "no" in answer or "nah" in answer or "nay" in answer or "course not" in answer or "don't" in answer or "dont" in answer or "not" in answer:
            exiting()
        elif answer in ["y", "yes", "yeah", "course", "ye", "yea", "yh", "do"] or "yes" in answer or "yeah" in answer or "course" in answer or "ye" in answer or "yea" in answer or "yh" in answer or "do" in answer:
        input_for_tts("\nPlease input something for the program to say: ")
        else:
            print("\nSorry, I didn't understand that. Please try again with yes or no.")

    except KeyboardInterrupt:

        exiting()

我目前用来转换它的代码:

from cx_Freeze import setup, Executable

setup(name='Text To Speech',
      version='0.1',
      description='A simple Text To Speech program, designed by Gameskiller01',
      executables = [Executable("Text To Speech.py")])

您需要告诉 cx_freeze 包含 idna

from cx_Freeze import setup, Executable

base = None

if sys.platform == 'win32':
    base = "Win32GUI"


executables = [cx_Freeze.Executable("Text To Speech.py", base=base)]

packages = ["idna"]
options = {
    'build_exe': {

        'packages':packages,
    },

}

cx_Freeze.setup(
    name = "Text To Speech",
    options = options,
    version = "0.01",
    description = 'A simple Text To Speech program, designed by Gameskiller01',
    executables = executables
)