title: Creating a Global Instance of a Class Inside of a Function
body: <p>So I'm writing a filter for the Minecraft terrain manipulation program MCEdit. The filter is written in Python 2 (That's the only thing MCEdit will read). MCEdit calls the filter by passing the variables level (Of type MCLevel), box and options to the user defined function perform(level, box, options). You can find the documentation on this here >> <a href="https://github.com/mcedit/pymclevel" rel="nofollow">https://github.com/mcedit/pymclevel</a></p>
  
  <p>I have written multiple filters before, so I know the general idea of how it works. Here is my code:</p>
  
  <pre><code>from pymclevel import *
  import random
  
  inputs = (("Replace", (0, 1, 255)), ("Of Damage", (0, 0, 15)), ("With", (1, 1, 255)), ("Of Damage ", (0, 0, 15)), ("This Percent of the Time", (50, 0, 100)), ("If it is Beside", (False)), ("Or Diagonal", (False)), ("Exclusively", (False)), ("To", (0, 1, 255)), ("Of Damage  ", (0, 0, 15)))
  
  def getBlock(x, y, z):
      global level
      return (level.blockAt(x, y, z), level.blockDataAt(x, y, z))
  
  def setBlock(x, y, z, block, data):
      global level
      level.setBlockAt(x, y, z, block)
      level.setBlockDataAt(x, y, z, data)
  
  def IsBeside(x, y, z, block, data):
      return (getBlock(x - 1, y, z) == (block, data) or getBlock(x + 1, y, z) == (block, data) or getBlock(x, y - 1, z) == (block, data) or getBlock(x, y + 1, z) == (block, data) or getBlock(x, y, z - 1) == (block, data) or getBlock(x, y, z + 1) == (block, data))
  
  def IsDiagonal(x, y, z, block, data):
      return (getBlock(x - 1, y - 1, z) == (block, data) or getBlock(x - 1, y, z - 1) == (block, data) or getBlock(x, y - 1, z - 1) == (block, data) or getBlock(x + 1, y + 1, z) == (block, data) or getBlock(x + 1, y, z + 1) == (block, data) or getBlock(x, y + 1, z + 1) == (block, data) or getBlock(x + 1, y + 1, z + 1) == (block, data) or getBlock(x - 1, y + 1, z + 1) == (block, data) or getBlock(x + 1, y - 1, z + 1) == (block, data) or getBlock(x + 1, y + 1, z - 1) == (block, data) or getBlock(x - 1, y - 1, z + 1) == (block, data) or getBlock(x - 1, y + 1, z - 1) == (block, data) or getBlock(x + 1, y - 1, z - 1) == (block, data) or getBlock(x - 1, y - 1, z - 1) == (block, data))
  
  def perform(level, box, options):
  
      Replace = options["Replace"]
      ReplaceData = options["Of Damage"]
      With = options["With"]
      WithData = options["Of Damage "]
      Percent = options["This Percent of the Time"]
      Beside = options["If it is Beside"]
      Diagonal = options["Or Diagonal"]
      Exclusive = options["Exclusively"]
      Check = options["To"]
      CheckData = options["Of Damage  "]
  
      mark = False
  
      for x in xrange(box.minx, box.maxx + 1):
          for z in xrange(box.minz, box.maxz + 1):
              for y in xrange(box.miny, box.maxy + 1):
                  if random.randint(1, 100) &lt;= Percent and getBlock(x, y, z) == (Replace, ReplaceData):
  
                      if Beside and not Diagonal and not Exclusive:
                          if IsBeside(x, y, z, Check, CheckData):
                              mark = True
  
                      elif not Beside and Diagonal and not Exclusive:
                          if IsDiagonal(x, y, z, Check, CheckData):
                              mark = True
  
                      elif Beside and not Diagonal and Exclusive:
                          if IsBeside(x, y, z, Check, CheckData) and not IsDiagonal(x, y, z, Check, CheckData):
                              mark = True
  
                      elif not Beside and Diagonal and Exclusive:
                          if not IsBeside(x, y, z, Check, CheckData) and IsDiagonal(x, y, z, Check, CheckData):
                              mark = True
  
                      elif Beside and Diagonal:
                          if IsBeside(x, y, z, Check, CheckData) and IsDiagonal(x, y, z, Check, CheckData):
                              mark = True
  
                      else:
                          mark = True
  
                      if mark:
                          level.setBlock(x, y, z, With, WithData)
                          mark = False
  </code></pre>
  
  <p>My problem is that I need to call getBlock and setBlock an absurd number of times, and it's quite likely that level will contain HUGE amounts of information (Enough that it could take multiple seconds just to copy it into a function). By extension, that means the filter could easily run for hours, most of that time just spent copying level. Naturally, I don't want to do that, and since python has no pass by reference, and I can't access the original variable that was passed into perform, I can only try and access the instance of level passed to perform from the other functions. That's where the global stuff comes in, which obviously doesn't work. Does anyone know of a way to make this work without passing level as a function argument to getBlock and setBlock? I don't care if it uses global or not, that was just my thought.</p>