4
$\begingroup$

I'm trying to make an inventory with 4 cells or more and 2 various items or more.

enter image description here

I want to check if the variable x is set to False. If so, then the cell1() function should be x set to True. The idea is if x is True then nothing should be collected. In principle, should represent x if the cell is empty or full. My problem is that x is always "False" after the function has finished??? Why does it work in Python but not in Blender?

x = "False"

def xReplace(value):
    global x
    x = value


def cell1():    
    if sens.positive and x == "False": # sens= message sensor
        var()                          # var()= function update text in cell1/ or end object
        xReplace("True")               # "change the value from global variable x"

    elif sens.positive and x == "True": 
        var2()                         # var2()= function update/set in cell2

cell1()
print(x)

console prints

True
False

I do not understand why it prints variable x twice, and why is the second line False? I think Blender makes two variables of the same name.? Because when I write print (x == x) then comes twice True. Why does the Blender in this way? Or is there another way to do it.

$\endgroup$
3
  • 1
    $\begingroup$ What exactly are you asking. it's unclear $\endgroup$
    – ruckus
    Commented Jan 2, 2015 at 0:06
  • $\begingroup$ can I change a global variable from a function? not copy the global variable and then change it. $\endgroup$
    – Anunaki
    Commented Jan 2, 2015 at 0:33
  • $\begingroup$ A global variable is able to be changed ad accessed by everything. $\endgroup$
    – ruckus
    Commented Jan 2, 2015 at 1:56

2 Answers 2

1
$\begingroup$

This is, no kidding, straight from my professors mouth.

There are three scopes of Variables; one does not apply to blender.

  • Local

  • Form-Level

  • Global

Local variables would be like game properties, or a material. They have effect on only those procedures and functions who posses them and objects/procedures designed to be affected by them via collision, near, ray, radar ect.

They can only be changed/accessed via the procedures/functions to which they belong.

Global variables (this is the real answer) can be changed, accessed, and modified by any/all procedures, functions, and objects.

This means Yes. If it is on one, it's on 'em all.

$\endgroup$
1
  • $\begingroup$ I don't know your exact situation, do what you think is right. What ever you are most comfortable with. $\endgroup$
    – ruckus
    Commented Jan 2, 2015 at 18:58
0
$\begingroup$

I have the same problem. I create global variable and then access it from two different classes: button changes it +1, panel draws it. However, while panel can always draw it, button CAN NOT change it - and yes, I used the global keyword inside the button class.

After some digging, my answer is: Blender can not create Python's global variables directly in a script.

My explanation of "Why?" comes from understanding of Blender internals:

  1. Blender developers decided that everything should go through Blender's API
  2. If everything goes through Blender's API, Blender can save it to a .blend file, which makes user happy
  3. If something goes around or works outside of Blender API, it can't be saved in .blend file (the Blender simply does not know about it) and some users would surely cry
  4. Blender's Script is always executed (for any action) whole again - thus our wanna-be global variable is created, changed, forgotten, created, changed, forgotten, etc.

Consider this example:

my_var = 1

def my_func():
     global my_var
     my_var = 2

print(my_var)
my_func()
print(my_var)

On Windows with Python 3.4, its double run leads to

C:\Python34\python test.py
1
2
C:\Python34\python test.py
1
2

As expected, python enviroment was terminated after first run and all its context was forgotten. When run be second time, Windows allocated new memory for the Python, where the code was executed again as new.

However, one would expect in Blender, whose thread/process is still running that such global variable would be remembered. IT IS NOT. Its double run using Text>Run Script or Alt+P twice in Blender's Text Editor mode leads to

1
2
1
2

instead of expected

1
2
2
3

While I do understand the need to save everything properly into .blend file, I do not agree with the Blender's policy: Use my API or Die. I am writing GPLed CAD for Blender and I will use my own portable HDF5 file to store scientific data properly. Blender is used only for visualisation and volume definition. So it does not need to and should not depend on .blend file at all (remember, portability). I want use python's global variables for my UI, but I can't.

Three workarounds are possible:

  1. Use Blender's types from bpy module
  2. Write another module with a python's global variable in it and import it into your script.
  3. Save your variable into file and load it

Hopefully, the Blender Developers will change their mind in future and will allow classic global variables in one script. Until then, I recommend the second option - import your another module with global variable in it. Just for completeness, the first crazy-for-beginner option may look like

bpy.types.Material.my_float = bpy.props.FloatProperty(name="unique-name-of-my-float")

The second option with new python module named my_module.py with single line

my_variable = 1

can be used in your original script as

import my_module

def my_func():
    my_module.my_var = 2

where the my_var will be remembered during whole Blender session and finally the third, little-extreme but always-working option is

f = open("C:\my_global_variable.txt", 'r')
my_global_variable = int(f.readline())
f.close()
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .