1

我正在编写一个程序,我正在使用espeak库来让它说话。问题是我已经编写了我的程序,但现在我想在开始时询问用户他是希望程序与他交谈还是仅仅依靠阅读。因此,如果他说是,则程序使用 using espeak,但如果他说否,则程序不使用espeak,所以我被困在 no 部分。

我想问一个问题并根据答案使用正确的函数,但问题是它是一个本地函数,所以当你使用espeak()它说的函数时

NameError: name 'espeak' is not defined 

这就是我想要的:

import os
ai_talk = False
# MAKE THE AI SPEAK, OR NOT
def speak_or_not():
    global ai_talk
    
    speak_or_n = input("Do you want me to speak or not?\nPS: input Y/N\n").casefold()
    while not ai_talk:
        if (speak_or_n == "y") or (speak_or_n == "yes"):
            def espeak(text):
                command = 'espeak -v +f2 -p25 '+'"'+text+'"'
                os.system(command)
                return
            ai_talk = True

        elif (speak_or_n == "n") or (speak_or_n == "no"):
            def espeak(text):
                return
            ai_talk = True

        else:
            speak_or_n = input("You can only input Y/N").casefold()
    return

speak_or_not()

print("Hello there! how are you doing?")
espeak("Hello there! how are you doing?")

那么有没有办法使该def espeak()功能在全局范围内工作,以便我可以将它用于我的程序的其余部分?

(除了处理孔东西并粘贴在没有espeak功能的no部分之外)

4

2 回答 2

1

以下是如何编写它以speak_or_not返回espeak函数。我添加了类型注释,以便更容易查看内部函数如何与外部函数交互——该speak_or_not函数返回 a Callable[[str], None](一个接受str参数并返回的函数None),并且两个版本都espeak匹配此类型。

import os
from typing import Callable

def speak_or_not() -> Callable[[str], None]:
    """Return a function that either makes the AI speak or is a no-op."""
    speak_or_n = input("Do you want me to speak or not?\nPS: input Y/N\n").casefold()
    while True:
        if speak_or_n in ("y", "yes"):
            def espeak(text: str) -> None:
                os.system(f'espeak -v +f2 -p25 "{text}"')
            return espeak
        if speak_or_n in ("n", "no"):
            def espeak(text: str) -> None:
                return
            return espeak
        speak_or_n = input("You can only input Y/N").casefold()

espeak = speak_or_not()

print("Hello there! how are you doing?")
espeak("Hello there! how are you doing?")

请注意,这global ai_talk不是必需的,因为该值从未在函数外部使用,实际上在函数内部它仅用于中断循环,如果return满足终止条件,则这是不必要的,因此即使在函数内部根本不需要价值。

于 2020-09-14T02:10:03.160 回答
0

如果你简单return espeak,你可以在主程序中保存你想要的定义。这就是 Python 装饰器的工作方式。这是一个简单的例子:

def fpick(flag):
    if flag:
        def display():
            print('flag was set')
    else:
        def display():
            print('flag was off')

    return display

display = fpick(True)
display()

display = fpick(False)
display()

输出:

flag was set
flag was off

 was set
flag

被关

于 2020-09-14T02:01:17.793 回答