Inheritance of Properties in Subclasses

In case anyone is still wondering about this or finds it through Google, I too was trying to use inheritance in a similar manner and was failing dismally in my efforts. And then just yesterday I read something in the API documentation which pointed to a way it can be achieved, in this case using a mixin as opposed to just a parent class for inheritance.

Let’s say I wanted to create a number of operators which share common properties, myint, mystring, myfloat. The following code illustrates how this can be achieved:

import bpy
from bpy.types import Operator
from bpy.props import IntProperty, StringProperty, FloatProperty


class CommonProps:
    '''Class containing common properties to
    be inherited by various operator classes'''


    myint = IntProperty(name="My integer", default=1)
    mystring = StringProperty(name="My string", default="Hello")
    myfloat = FloatProperty(name="My float", default=3.141592654)


class TestOp1(Operator, CommonProps):
    bl_label = "My Test Op1"
    bl_idname = "test.op1"
    bl_options = {'REGISTER', 'UNDO'}


    op2prop = StringProperty(name="Op1 only prop", default="Will only appear in Op1")


    def invoke(self, context, event):
        wm = bpy.context.window_manager
        return wm.invoke_props_dialog(self)


    def execute(self, context):
        return {'FINISHED'}


class TestOp2(Operator, CommonProps):
    bl_label = "My Test Op2"
    bl_idname = "test.op2"
    bl_options = {'REGISTER', 'UNDO'}


    op2prop = StringProperty(name="Op2 only prop", default="Will only appear in Op2")


    def invoke(self, context, event):
        wm = bpy.context.window_manager
        return wm.invoke_props_dialog(self)


    def execute(self, context):
        return {'FINISHED'}


bpy.utils.register_module(__name__)
bpy.ops.test.op1('INVOKE_DEFAULT')
#bpy.ops.test.op2('INVOKE_DEFAULT')

The script defines two operators, TestOp1 and TestOp2, which appear in popups just for illustrative purposes. Each defines a single property, but you will also note that each shows the three common properties we are interested in above.

Now, each of these operators still inherits from bpy.types.Operator directly, however each also inherits from the mixin class CommonProps where the three common properties are declared. For those who aren’t aware, “mixin” is the name given to a class which defines properties and functionality which can be shared by several classes alongside a class’s parent class via multiple-inheritance, which is exactly what is going on here.

@BlenderHawkBob if you’re still out there and reading this, the following can be done to your code to make inheritance work:

class CommonProps:
    s = StringProperty(name="s",default="ABC")


class Base(bpy.types.PropertyGroup, CommonProps):
    pass
class Child(bpy.types.PropertyGroup, CommonProps):
    pass


class AppPropertyGroup(bpy.types.PropertyGroup):


   b = PointerProperty(name="b", type=Base)
   c = PointerProperty(name="c", type=Child)


   def print_self (self, context):
      print ( "App Members:" )
      print ( " b.s = " + self.b.s ) # OK
      print ( " c.s = " + self.c.s ) # Fails



Of course here the names Base and Child don’t make any sense because they are both in fact children of CommonProps. However, this should achieve what it was you were trying to do in the first place.

For reference, this approach was suggested here:

http://www.blender.org/documentation/blender_python_api_2_70_release/bpy.types.Panel.html

specifically under the “Mix-in Classes” section:

“A mix-in parent class can be used to share common properties and Menu.poll function.”

1 Like