Python邮件发送程序选择邮箱服务商后对应变量无法定义的问题咨询
问题核心根因拆解
你碰到的这些反常运行效果,本质都是两个Python语法认知偏差导致的:
- Python的
else只和离它最近、同缩进层级的if配对,根本不会跨前面所有独立写的if形成统一的判断分支组。你现在的代码结构相当于写了4个完全独立的判断块:- 判断输入是不是Gmail,匹配就给
emailProvider赋值 - 判断输入是不是带感叹号的“Yahoo!”,匹配就赋值
- 判断输入是不是不带感叹号的“Yahoo”,匹配就赋值
- 判断输入是不是Outlook,不匹配就走else打印报错
也就是说,哪怕你前面三个判断全部命中、把SMTP服务器值赋对了,只要最后一个“是不是Outlook”的判断不成立,就一定会触发else的报错提示——这就是为什么不管你输什么受支持的服务商,都能看到错误提示的原因。
- 判断输入是不是Gmail,匹配就给
- 你尝试写的
if emailServer == 'Gmail' = True:是完全不符合Python语法的:==是比较判断运算符,=是赋值运算符,不能把前面的判断结果再用=给常量True赋值,这种代码Python解释器根本跑不起来。 - 至于程序打印了错误提示还能继续往下走流程,也是因为这几个独立的if块没有做流程中断处理,else里只打了一行字,自然会继续执行后面要你输入邮箱地址的代码。
这也刚好解释了你为什么直接把emailProvider的默认值设成Gmail之后,后续流程就能正常跑:因为你绕过了那个错误配对的else分支的干扰。
规范解法1:正确串联的elif分支结构
要让所有判断形成统一的分支组,必须把第一个if之后的所有独立判断改成elif(也就是else if的缩写),整个分支组只要有一个条件命中,就会自动跳过后面所有判断、不会再触发else的报错:
# Establish email server connection print('Welcome to Brett\'s email program! Let\'s send a message.') emailServer = input('First, I need your email provider: Gmail, Yahoo, or Outlook?\n') # 所有分支用if/elif串联,最后统一挂else if emailServer == 'Gmail': emailProvider = 'smtp.gmail.com' elif emailServer in ('Yahoo!', 'Yahoo'): # 把两个Yahoo的匹配条件合并,不用重复写赋值逻辑 emailProvider = 'smtp.mail.yahoo.com' elif emailServer == 'Outlook': emailProvider = 'smtp.office365.com' # Found this server name on serversmtp.com # TODO: Test other email providers (iCloud, AT&T, Comcast, Verizon) else: print('I don\'t know that email provider. Please try again.')
实用小优化:用户输入时经常不小心带前后空格、大小写错配,你可以在判断前给输入值做简单清洗,比如emailServer = emailServer.strip().title(),能减少很多无意义的匹配失败。
规范解法2:字典映射实现
当后续要支持的邮箱服务商变多,写一长串if/elif会越来越难维护,用字典做键值对映射是最简洁的方案:后续新增支持的服务商只需要往字典里加一行映射,完全不用改动判断逻辑:
# 提前定义服务商与SMTP服务器的映射字典 PROVIDER_SMTP_MAP = { "gmail": "smtp.gmail.com", "yahoo": "smtp.mail.yahoo.com", "yahoo!": "smtp.mail.yahoo.com", "outlook": "smtp.office365.com", # 后续要加iCloud、AT&T、Comcast等直接往这里补键值对就行 } # Establish email server connection print('Welcome to Brett\'s email program! Let\'s send a message.') # 获取输入时自动去掉前后空格,统一转小写做匹配,降低匹配失败概率 emailServer = input('First, I need your email provider: Gmail, Yahoo, or Outlook?\n').strip().lower() # 直接从字典取对应值,没匹配到就返回None emailProvider = PROVIDER_SMTP_MAP.get(emailServer) if not emailProvider: print('I don\'t know that email provider. Please try again.')
这种写法的逻辑完全解耦:你调整支持的服务商列表、修改SMTP服务器地址,都不需要去碰流程判断的代码,维护成本比长串if/elif低很多。
内容的提问来源于stack exchange,提问作者Brett A.
相关产品推荐
相关产品推荐

