HOw to make a variable in a function into a global variable.

I have a method like this:

def MouseMotion(task):
  if base.mouseWatcherNode.hasMouse():
    mouseXPos = base.mouseWatcherNode.getMouseX()
    mouseYPos = base.mouseWatcherNode.getMouseY()
    mouseMoved(mouseXPos, mouseYPos)
  else:
    mouseXPos = 0
    mouseYPos = 0
  return Task.cont

but when i try to read what mouseXPos or mouseYPos is it says their not defined. How can i make it so that this function makes them availible to the whole program?

try declaring your ‘global’ variables before they’re encountered, at a higher scope (less indent), e.g. at the top of your file. You may also need to put the line

global myVar

in your method before using myVar, after declaring myVar at the highest/global level

If all you need is to access the same variable from multiple methods within a single class, the more appropriate thing to do would be to make a class-level variable “self.myVar”. Really, good practice is to put your whole game in a new game class and instantiate it once before run().

I use multiple classes in my game for clarity and simplicity. This may not be the best way, since it is something I figured out myself, but it seems to work for me.

In game.py, I have:

import starfield
import player

class game():

  def __init__():

     self.starfield = starfield.starfield(self)
     self.player = player.player(self)

     .
     .
     .

Then in player.py I have:


class player(self,game)

  def __init__(self,game):
  
     self.game = game
     .
     .
     .

And the same idea inside of starfield. This way, game can access any class-wide variables in player by using self.player.MouseX for example, and player can access the class variables in game by using self.game.myVar

This allows things to be separated into as many classes as I need, but I can still get at the variables that I require. If I really need to get at something in starfield from player, I can technically do self.game.starfield.someVar but that is sort of evil, and probably needs to be reconsidered for being in game at that point.

Hope this makes sense, and if I am doing something horribly wrong, please be gentle in correcting me!

I do this too, you’re not alone!

hm. while this is certainliy possible. it nullifies some advantages of using classes/objects.
the idea behind those would be to use isolated objects which can communicate with each other using defined methods. so when you change something you only have to care about a small piece of code, as long as input and output are ok you can freely mess around inside.

if you start to make variables accessable between classes without using methods for setting/getting … you’ll ultimatively end up with a big network of connections between many many objects which is terribly hard to keep track of. removing one part may break 3 others somewhere else and you’r not aware of it.

you might want to concider this when writing applications with more than just a few lines of code

I’ve seen that sort of technique used, and in The Industry no less. It’s great if you have, e.g., a game class with its own scene root node independent of render (e.g. so you can keep all game-related stuff inside the Game class) and you have multiple smaller subsets of the game each of which need access to the game root or other general-use metadata. However, I agree you need to do that sort of thing intentionally and sparingly. Global-scoping the bulk of your program generally makes for an ugly untraceable mess.

I guess C++ has spoiled me for far too long, but I am curious – How do you handle things like shared constants in Python? For example, my Projectile class and my Player class really should be sharing the same set of collision masks.

The only solution I can think of is to create a “global” class that defines such things and then import it into each distinct class.

well you can simply use a getCollisionmask() function which returns the collision mask in question. this way you can sorta request the collision mask.
in the end, you can do whatever you want. it’s just a matter of personal taste and code-maintainability.

globals are bad.

If multiple function need access to a valuable i suggest to make a class and make your global instance variable.

Huh? He was asking about global constants. Global constants are good.

These are usually done by declaring them at the top level of a module (a .py file) that is imported wherever they are needed.

David