如何解决nonetype 对象不可订阅 pysimplegui
我正在尝试同时学习 python 和 pysimplegui。我也老了,这无济于事!
我正在和我 10 岁的儿子(盲导盲人)一起编写练习程序,但遇到了一个我无法解决的问题。
基本上,该程序可让您输入要从多少个号码中选择以及要选择多少个号码,然后计算获胜的几率。点击生成为您随机选择数字并将结果打印到 txt 文件以记录您的选择。
一切正常,但是当我关闭窗口时,我收到了一个无法解决的非类型错误。
你们中的任何一位天才都可以提供帮助吗? 这是违规行
n=int(values['--tn--'])
from os import close
import random
from tkinter import Scrollbar
import PySimpleGUI as sg
import datetime
import math
from time import sleep,time
from PySimpleGUI.PySimpleGUI import Open,WIN_CLOSED,main
import sys
sg.theme('Reddit')
layout = [
[sg.In(size=(5,1),k="--tn--" ) ]+[sg.Text('Enter total amount of
numbers',size=(35,1))],[sg.In(size=(5,k="--pn--")]+[sg.Text('Enter how many numbers
you are picking',[sg.Text('Win odds')]+[sg.ML(background_color='light
coral',text_color='white',key='--oddout--',size=(50,2))],[sg.ML(size=(20,30),key='--main--')],[sg.Submit('Odds',key='--odds--')]+[sg.Submit('Generate',key='--
gen--')]+ [sg.Cancel('Cancel')]+[sg.Save(key='--save--')]+
[sg.CloseButton('Close',pad=(100,0))]
]
window = sg.Window('Lotto number generator',layout)
while True:
event,values = window.read()
n=int(values['--tn--'])
rr=int(values['--pn--'])
nf = math.factorial(n)
rf = math.factorial(rr)
winodds = (nf/(rf*math.factorial(n-rr)))
winodds = int(winodds)
Now = datetime.datetime.Now()
if event == WIN_CLOSED:
window['--tn--'].update('1')
break
if event == '--gen--':
r = random.sample(range(1,n),rr)
for i in r:
window['--main--'].print(i)
if event == '--odds--':
window['--oddout--'].print("Your chances of winning are
",f'{winodds:,d}'," to 1,Good Luck")
if event == 'Cancel':
window['--oddout--'].update('')
window['--tn--'].update('')
window['--pn--'].update('')
if event == '--save--':
sys.stdout = open("lotto.txt","w")
print(values['--main--'])
sys.stdout=close(fd=0)
window.close()
解决方法
有什么不好的,
- 您应该先检查窗口关闭事件,而不是先处理
event,values
其他情况,如下代码。如果不是,您可能会得到event,values
作为None,None
,那么values['--tn--']
将与None['--tn--']
相同。这就是您获得TypeError: 'NoneType' object is not subscriptable
的原因。
while True:
event,values = window.read()
if event in (sg.WINDOW_CLOSED,'Close'):
break
# process other events from here
window.close()
- 在您的输入字段中,
values['--tn--']
或values['--pn--']
的整数格式可能不正确,因此以下代码可能会失败ValueError: invalid literal for int() with base 10
n=int(values['--tn--'])
rr=int(values['--pn--'])
这是我避免问题的方法,
def integer(string):
try:
value = int(string)
except:
value = None
return value
for string in ("10.5","","10"):
value = integer(string)
if value is None:
print(f"{repr(string)} is not a legal integer string !")
else:
print(f"{repr(string)} converted to {value} !")
'10.5' is not a legal integer string !
'' is not a legal integer string !
'10' converted to 10 !
- 基本上,在您单击窗口的关闭按钮
X
后,窗口会被销毁,因此您不应对其进行任何更新。
if event == WIN_CLOSED:
# window['--tn--'].update('1')
break
,
event,values = window.read()
正在返回 None
。 None['--tn--']
不存在,因为 None
没有属性,因此出现错误消息。您已使用该测试来避免这种情况,但将其移至下方以尝试使用缺失的属性。因此出现错误。
使用 linting 工具提示您对语法进行调整,这将破坏您的代码和良好实践警告也是值得的。我使用pylint和flake8。以下内容解决了您的特定错误消息,并对 linter 消息进行了一些整理。还有一些警告 - 很好的学习练习:)
"""Learning program."""
from os import close
import random
import PySimpleGUI as sg
import datetime
import math
from PySimpleGUI.PySimpleGUI import Open,WIN_CLOSED,main
import sys
sg.theme('Reddit')
layout = [
[sg.In(size=(5,1),k="--tn--")] +
[sg.Text('Enter total amount of numbers',size=(35,1))],[sg.In(size=(5,k="--pn--")] +
[sg.Text('Enter how many numbers you are picking',[sg.Text('Win odds')] +
[sg.ML(
background_color='light coral',text_color='white',key='--oddout--',size=(50,2)
)],[sg.ML(size=(20,30),key='--main--')],[sg.Submit('Odds',key='--odds--')] +
[sg.Submit('Generate',key='--gen--')] +
[sg.Cancel('Cancel')] +
[sg.Save(key='--save--')] +
[sg.CloseButton('Close',pad=(100,0))]
]
window = sg.Window('Lotto number generator',layout)
while True:
event,values = window.read()
# Moved the next three lines up and commented update which also errors
if event == WIN_CLOSED:
# window['--tn--'].update('1')
break
n = int(values['--tn--'])
rr = int(values['--pn--'])
nf = math.factorial(n)
rf = math.factorial(rr)
winodds = (nf/(rf*math.factorial(n-rr)))
winodds = int(winodds)
now = datetime.datetime.now()
if event == '--gen--':
r = random.sample(range(1,n),rr)
for i in r:
window['--main--'].print(i)
if event == '--odds--':
window['--oddout--'].print(
"Your chances of winning are",f'{winodds:,d}'," to 1,Good Luck"
)
if event == 'Cancel':
window['--oddout--'].update('')
window['--tn--'].update('')
window['--pn--'].update('')
if event == '--save--':
sys.stdout = open("lotto.txt","w")
print(values['--main--'])
sys.stdout = close(fd=0)
window.close()
Flake8 尤其会提示您遵循没有明显实际目的的实践。稍后,随着您使用更多语言,flake8 提示的好处是良好的习惯,最终会带来巨大的好处。
,当您关闭窗口时,event
和 values
未设置,请参见下面的示例。
在调试时,打印出 event
和 values
的当前值是一个很好的做法,以便能够检查您是否得到了您认为会得到的结果,如下所示:
def test():
layout = [[sg.In(size=(5,k="--tn--"),sg.Text('Enter total amount of numbers',k="--pn--"),sg.Text('Enter how many numbers you are picking',[sg.Text('Win odds'),sg.ML(background_color='light coral',2))],key='--odds--'),sg.Submit('Generate',key='--gen--'),sg.Cancel('Cancel'),sg.Save(key=' - -save - -'),sg.CloseButton('Close',0))]
]
window = sg.Window('Lotto number generator',layout)
while True:
event,values = window.read()
print(f'event = {event},values = {values}')
if event == WIN_CLOSED:
break
window.close()
当你关闭窗口时,你得到
event = None,values = {'--tn--': None,'--pn--': None,'--oddout--': None,'--main--': None}
因此,使用 if event == WIN_CLOSED:
开始主循环很重要(并在这种情况下中断循环)。只有在此之后,您才能继续处理各种事件和值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。