14

I'm writing Python scripts for Blender for a project, but I'm pretty new to the language. Something I am confused about is the usage of static variables. Here is the piece of code I am currently working on:

class panelToggle(bpy.types.Operator):
    active = False

    def invoke(self, context, event):
        self.active = not self.active
        return{'FINISHED'}

class OBJECT_OT_openConstraintPanel(panelToggle):
    bl_label = "openConstraintPanel"
    bl_idname = "openConstraintPanel"

The idea is that the second class should inherit the active variable and the invoke method from the first, so that calling OBJECT_OT_openConstraintPanel.invoke() changes OBJECT_OT_openConstraintPanel.active. Using self as I did above won't work however, and neither does using panelToggle instead. Any idea of how I go about this?

4
  • Okay, it seems I can use self.__class__.active or type(self).active to let the method inherit properly. Thanks! Commented Aug 13, 2010 at 9:52
  • Why are you using static variables in the first place? That doesn't seem sensible. Is this active attribute some kind of global, shared among all PanelToggle instances? If so, why isn't it actually global? Or why isn't in some more global shared object? Commented Aug 13, 2010 at 10:09
  • I want each panelToggle subclass to have its own "active" variable that can be accessed without creating an instance. If I understand the use of the "global" keyword correctly, I'd have to insert a 'global active' line first in 'invoke(..)' before just using active like a local variable. Doing this gives an error saying the global name 'active' is not defined. I'm not sure I understand what's wrong with my approach, however. Commented Aug 13, 2010 at 11:17
  • Why class-level? Clearly you want each subclass to have a variable. Why is it at the class level? That's what makes little sense. Why isn't this an ordinary instance variable? Commented Aug 13, 2010 at 15:45

2 Answers 2

22

use type(self) for access to class attributes

>>> class A(object):
 var  = 2
 def write(self):
   print(type(self).var)
>>> class B(A):
 pass
>>> B().write()
2
>>> B.var = 3
>>> B().write()
3
>>> A().write()
2

UPDATE

for a classmethod is event easier, and most natural

class A(object):
     var  = 2
     @classmethod
     def write(cls):
       print(cls.var)

and a staticmethod should not depend on the instance type, so such form of dispatch is possible here

Sign up to request clarification or add additional context in comments.

5 Comments

is type(self) in any way different from using self.__class__?
It is not at the moment. But some features can be implemented later. Also you can do some monkey patch to type function.
I'm using Python 3.8.5 and I noticed a difference: I could not modify type(self).var from inside an instance method of the class. I had to use self.__class__.var in order to be able to modify it within an instance method. Not sure why?
is there a way to accomplish this if write were a static method?
@ekkis updated an answer a little bit
4

You can access active through the class it belongs to:

if panelToggle.active:
    # do something

If you want to access the class variable from a method, you could write:

def am_i_active(self):
    """ This method will access the right *class* variable by
        looking at its own class type first.
    """
    if self.__class__.active:
        print 'Yes, sir!'
    else:
        print 'Nope.'

A working example can be found here: http://gist.github.com/522619


The self variable (named self by convention) is the current instance of the class, implicitly passed but explicitely recieved.

class A(object):

    answer = 42

    def add(self, a, b):
        """ ``self`` is received explicitely. """
        return A.answer + a + b

a = A()

print a.add(1, 2) # ``The instance -- ``a`` -- is passed implicitely.``
# => 45

print a.answer 
# => print 42

2 Comments

Yes, but I want to be able to do the same with OBJECT_OT_openConstraintPanel. I want it to have its own static "active" variable, inherited from panelToggle. I also want to make the "invoke" method work in the subclass (access its own "active" variable instead of its parent's)
Edited my post and added sample code in gist.github.com/522619, hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.