Difference between declaring props in the register() or in the main body of the addon?


I sometimes see in some scripts that (some) props are declared in the register() callbacks like

    from bpy.types import WindowManager

    WindowManager.myprop = StringProperty( name="my prop", default="") 

This example can be seen in ui_previews_dynamic_enum.py from the templates

We can declare these types in the body as well. So I am wondering if this is just a convenience thing or there is more to it than what is seen here?

the difference is not the declaration itself, it‘s the data path that will hold and maintain the resulting property. In the given example, you will be able to access the prop from bpy.context.wm.myprop. Note that what you have effectively done here is to extend the type WindowManager by an additional property. This can be done with ID types (such as bpy.types.Object, bpy.types.Scene,…).

If you define it in the body of a class, and the class is properly registered, the prop will be accessed from instances of said class. So for example, if your class defines an operator which registers as a mesh operator, you will see your property as bpy.ops.mesh.my_operator.myprop. Note that in this case, you have defined an entirely new operator, instead of extending an existing one with a prop.