在没有类的情况下,变量(Python / Pygame)的范围有问题

问题描述 投票:0回答:3

我在我的

globals.py
上创建了一个变量,在名为generatePlaylist的函数上对其进行了一些修改,并尝试在另一个函数上使用她。

  1. globals.py
import pygame as Py

selectedSong = None
  1. 功能
    generatePlaylist
    和选择
    playlist.py
from globals import *
import os

songs = os.listdir('./assets/songs')  

def generatePlaylist(font, event):
    for index, song in enumerate(songs):
        rectIndex = Py.Rect(20, 25 + (50 * (index + 1)), 260, 40)
        rectIndexPosition = (20, 25 + (50 * (index + 1)))
        rectIndexWidth = 260
        rectIndexHeight = 40
        Py.draw.rect(screen, 'gray', rectIndex)
        text_surface = font.render(song, True, (0, 0, 0))
        text_rect = text_surface.get_rect(center=rectIndex.center)
        screen.blit(text_surface, text_rect)

        selected = selection(event, rectIndexPosition, rectIndexWidth, rectIndexHeight, song)
        if selected is not None:
            selectedSong = selected
            print(selectedSong)

        if index == len(songs) - 1:
            text_surface = font.render(song, True, (0, 0, 0))
            text_rect = text_surface.get_rect(center=rectIndex.center)
            screen.blit(text_surface, text_rect)
            rectDownload = Py.Rect(20, 25 + (50 * (index + 2)), 260, 40)
            Py.draw.rect(screen, 'gray', rectDownload)
            text_surface = font.render("Download", True, (0, 0, 0))
            text_rect = text_surface.get_rect(center=rectDownload.center)
            screen.blit(text_surface, text_rect)

def selection(event, rectIndexPosition, rectIndexWidth, rectIndexHeight, song):
    if event.type == Py.MOUSEBUTTONUP:
            if rectIndexPosition[0] <= event.pos[0] <= rectIndexPosition[0] + rectIndexWidth and \
               rectIndexPosition[1] <= event.pos[1] <= rectIndexPosition[1] + rectIndexHeight:
                return(song)
    return None    

我的打印显示当我点击时

selectedSong
已更新。

  1. 我的
    main.py
import pygame as Py
from render import *
from buttonMusic import *
from playlist import *
from globals import *

Py.init()

continuer = True
script_folder = os.path.dirname(os.path.abspath("C:\\Users\\Anthony\\OneDrive\\Bureau\\playerMusic\\assets"))
font_path = os.path.join(script_folder, 'assets', 'font', 'Roboto-Black.ttf')
font = Py.font.Font(font_path, 18)

while continuer:
    render(font)
    for event in Py.event.get():
        if event.type == Py.QUIT:
            continuer = False
        generatePlaylist(font, event)
        reculeButton(event)
        randomButton(event)
        playButton(event)
        pauseButton(event)
        stopButton(event)
        advanceButton(event)
        loopButton(event)
        upButton(event)
        downButton(event)
        muteButton(event)
Py.quit()

在generatePlaylist之后调用playButton

  1. buttonMusic.py 上的播放按钮
from musicFunction import *
from globals import *

def playButton(event):
   if event.type == Py.MOUSEBUTTONDOWN:
      if imagePlayPosition[0] <= event.pos[0] <= imagePlayPosition[0] + imagePlay.get_width() and \
         imagePlayPosition[1] <= event.pos[1] <= imagePlayPosition[1] + imagePlay.get_height():
         print(selectedSong)
         if selectedSong is not None:
            play()

当我点击时,我的打印会一次又一次地停留在

None
上。 5) 不确定你需要它,但我的功能
play
musicFunction.py

def play():
    mx.music.load(f'./assets/songs/{selectedSong}')
    mx.music.play()

如果您需要,我可以给您我的 GitHub 存储库,感谢您花时间解决我的问题。

哦,一个新的空间来解释我的问题,我尝试了很多东西。很难解释什么是将我的变量从全局变量更改为函数参数等等。我所期望的只是找到一个可以向我解释为什么它不起作用的人。

python scope
3个回答
1
投票

你做错的是这一行:

from globals import *

这告诉 python 为每个模块提供自己的副本,在本例中:

selectedSong = None

每个模块然后继续修改自己的变量。

您应该阅读 Ned Batchelder 的这篇博客文章

作为快速解决方案,我可以建议:

  1. 全局.py
selectedSong = None

然后,作为所需其他更改的示例:

  1. 函数generatePlaylist并在playlist.py上进行选择
import globals
import os

songs = os.listdir('./assets/songs')  

def generatePlaylist(font, event):
    for index, song in enumerate(songs):
        rectIndex = Py.Rect(20, 25 + (50 * (index + 1)), 260, 40)
        rectIndexPosition = (20, 25 + (50 * (index + 1)))
        rectIndexWidth = 260
        rectIndexHeight = 40
        Py.draw.rect(screen, 'gray', rectIndex)
        text_surface = font.render(song, True, (0, 0, 0))
        text_rect = text_surface.get_rect(center=rectIndex.center)
        screen.blit(text_surface, text_rect)

        selected = selection(event, rectIndexPosition, rectIndexWidth, rectIndexHeight, song)
        if selected is not None:
            globals.selectedSong = selected
            print(globals.selectedSong)
    ...

使用形式:

globals.selectedSong
,然后首先引用模块
globals
,然后引用该模块内的变量。现在,每个以这种方式引用
globals
的模块都将引用 selectedSong
same
实例。


0
投票

代码很多,但我想我可以看到你问题的核心。

  1. 在Python中,“全局变量”实际上只在它们创建的文件中可见。然而,不同文件中的变量可能都指向同一个对象。

  2. import

    语句创建变量,就像赋值语句一样。

    
    

  3. import globals

    创建一个名为

    globals
    的变量,并分配从文件
    globals.py
    创建的模块。请注意,该模块仅创建一次,因此您可以从具有相同导入语句的任何文件中看到相同的模块。文件中的全局变量成为模块对象上的属性。
    
    

  4. from globals import *

    globals.py
    获取全局变量,并在当前文件中为它们创建变量。它不允许您访问模块对象。分配给这些变量之一不会影响模块。
    
    

  5. 因此您需要执行
import globals

并使用

globals.selectedSong = selected
修改模块以使更改在其他文件中可见。
一般来说,

from x import *

会让事情变得非常困难,因为你看不到代码中的变量是在哪里声明的,所以几乎不可能在任何复杂的程序中看到你的代码在做什么。

    


0
投票

对于全局部分

selectedSong = None def set_selected_song(song): global selectedSong selectedSong = song def get_selected_song(): global selectedSong return selectedSong

播放列表部分

selected = selection(event, rectIndexPosition, rectIndexWidth, rectIndexHeight, song) if selected is not None: selectedSong = selected set_selected_song(selectedSong)

按钮部分

def playButton(event): if event.type == Py.MOUSEBUTTONDOWN: if imagePlayPosition[0] <= event.pos[0] <= imagePlayPosition[0] + imagePlay.get_width() and \ imagePlayPosition[1] <= event.pos[1] <= imagePlayPosition[1] + imagePlay.get_height(): selectedSong = get_selected_song() print(selectedSong) if selectedSong is not None: play()

还有游戏部分

def play(): mx.music.load(f'./assets/songs/{get_selected_song()}') mx.music.play()

© www.soinside.com 2019 - 2024. All rights reserved.