如何解决当类在函数中时,为什么类中的全局行为会有所不同?
我正在尝试使用 ginput
来注册地图上的点击,并想使用 matplotlib 小部件添加操作按钮。在下面的代码中,我可以通过将 action 的值声明为 global
将其传递回主代码。如果我点击地图,action=0,如果我点击按钮,action=1,根据需要。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
class Index:
def test(self,event):
global action
action=1
# fake data
x=np.arange(30)
y=x**2
fig,ax=plt.subplots()
ax.plot(x,y)
callback = Index()
buttonname=['test']
colors=['white']
idx=[0.2]
bax,buttons={},{}
# set up list of buttons.
for i,col,button in zip(idx,colors,buttonname):
bax[button] = plt.axes([0.92,i,0.07,0.07])
buttons[button] = Button(bax[button],button,color=col,hovercolor='green')
buttons[button].on_clicked(getattr(callback,button))
# register click on plot
while True:
pts=plt.ginput(1)
plt.pause(0.5)
print("action is ",action)
action=0 # reset
但我的困惑是,如果我将完全相同的代码放在 def 块中,则 action 的值不再传回,action
始终为零。
def subtest():
class Index:
def test(self,event):
global action
action=1
# fake data
action=0
x=np.arange(30)
y=x**2
fig,ax=plt.subplots()
ax.plot(x,y)
callback = Index()
buttonname=['test']
colors=['white']
idx=[0.2]
bax,{}
# set up list of buttons.
for i,buttonname):
bax[button] = plt.axes([0.92,0.07])
buttons[button] = Button(bax[button],hovercolor='green')
buttons[button].on_clicked(getattr(callback,button))
# register click on plot
while True:
pts=plt.ginput(1)
plt.pause(0.5)
print("action is ",action)
action=0 # reset
res=subtest()
我很困惑为什么会发生这种情况。我尝试将类定义移到主代码中,但这没有帮助。我对任何类型的解决方案都感到高兴(例如,通过参数传递动作,我不知道如何处理小部件),因为我认为 global
的使用经常令人皱眉。但基于 global
的解决方案也很好。
解决方法
import discord
from discord.ext import commands
import youtube_dl
TOKEN = "Token here"
bot = discord.ext.commands.Bot(command_prefix = "s ");
@bot.event
async def on_ready():
channel = discord.utils.get(bot.get_all_channels(),id=794444804607574026)
await channel.connect()
@bot.command(name="play")
async def play(ctx,url):
player = await voice_client.create_ytdl_player(url)
player.start()
bot.run(TOKEN)
中的 action
是子测试的局部,而 subtest
中的 action
是全局的。在 Index.test
中声明 action
global,或在 subtest
中使用 nonlocal
。
(我怀疑没有全局变量可能有更好的解决方案,但由于我不熟悉 GUI 工具包,我将把它留给其他人。)
,您想查看这篇文章 on closures 和 this other article on closures。我认为您需要在类和函数之外声明 action,然后在类中使用 global 引用它。
我认为您不需要使用类 - 您可以通过围绕函数传递变量、布尔值、字典并实现相同的目的。
您可以使用“on_click”事件来执行您想要的操作,请参阅此小部件教程 widget tutorial 和 this on matplotlib event handling
这是使用“全局”来影响状态更改的示例代码。最好传递一个变量或使用事件来触发您希望状态影响的任何内容。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
state = False
def change_state(btn_action):
#do something
btn_action= not(btn_action)
return btn_action
def grid(val):
global state
#do something
state =change_state(state)
print(state)
ax.grid()
fig.canvas.draw()
#reset value
state =change_state(state)
print(f'resetting state to {state}')
# fake data
x=np.arange(30)
y=x**2
#create fig,ax
fig =plt.figure()
ax= fig.subplots()
p,= ax.plot(x,y)
# set up list of buttons.
buttonname=['test']
colors=['white']
idx=[0.2]
bax,buttons={},{}
for i,col,button in zip(idx,colors,buttonname):
bax[button] = plt.axes([0.92,i,0.07,0.07])
buttons[button] = Button(bax[button],button,color=col,hovercolor='green')
buttons[button].on_clicked(grid)
#show plot
fig.canvas.draw()
plt.show()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。