﻿<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ja">
	<id>https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=Dev%3A2.5%2FPy%2FAPI%2FDynamic_Creation_of_Operators</id>
	<title>Dev:2.5/Py/API/Dynamic Creation of Operators - 版の履歴</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.blender.jp/index.php?action=history&amp;feed=atom&amp;title=Dev%3A2.5%2FPy%2FAPI%2FDynamic_Creation_of_Operators"/>
	<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:2.5/Py/API/Dynamic_Creation_of_Operators&amp;action=history"/>
	<updated>2026-08-02T08:18:48Z</updated>
	<subtitle>このウィキのこのページに関する変更履歴</subtitle>
	<generator>MediaWiki 1.31.0</generator>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=Dev:2.5/Py/API/Dynamic_Creation_of_Operators&amp;diff=100137&amp;oldid=prev</id>
		<title>Yamyam: 1版 をインポートしました</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:2.5/Py/API/Dynamic_Creation_of_Operators&amp;diff=100137&amp;oldid=prev"/>
		<updated>2018-06-28T19:39:08Z</updated>

		<summary type="html">&lt;p&gt;1版 をインポートしました&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ja&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;← 古い版&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #222; text-align: center;&quot;&gt;2018年6月28日 (木) 19:39時点における版&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;ja&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(相違点なし)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Yamyam</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.blender.jp/index.php?title=Dev:2.5/Py/API/Dynamic_Creation_of_Operators&amp;diff=100136&amp;oldid=prev</id>
		<title>2011年2月19日 (土) 16:30にwiki&gt;Mindronesによる</title>
		<link rel="alternate" type="text/html" href="https://wiki.blender.jp/index.php?title=Dev:2.5/Py/API/Dynamic_Creation_of_Operators&amp;diff=100136&amp;oldid=prev"/>
		<updated>2011-02-19T16:30:03Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新規ページ&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Page/Header|2.5x|Dev:2.5/Py/API/Overview|}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
In Blender 2.5 operators are automatically registered (using a metaclass), so Blender can find them. This is normally very convenient, but when you're creating operators dynamically it might cause problems.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
== Problems and solutions ==&lt;br /&gt;
Example of a normal operator declaration that is automatically registered correctly:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import bpy&lt;br /&gt;
&lt;br /&gt;
class Foobar(bpy.types.Operator):&lt;br /&gt;
    ''''''&lt;br /&gt;
    bl_idname = &amp;quot;foo.bar&amp;quot;&lt;br /&gt;
    bl_label = &amp;quot;FooBar!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    def execute(self, context):&lt;br /&gt;
        print(&amp;quot;foobar&amp;quot;)&lt;br /&gt;
        return {'FINISHED'}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When you're dynamically creating operators, you might do something like this (which doesn't work):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import bpy&lt;br /&gt;
&lt;br /&gt;
my_names = [&amp;quot;Foo&amp;quot;, &amp;quot;Bar&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
def invoke(self, context, event):&lt;br /&gt;
    print(self.bl_description)&lt;br /&gt;
    return{'FINISHED'}&lt;br /&gt;
&lt;br /&gt;
for name in my_names:&lt;br /&gt;
    my_class = type(name, (bpy.types.Operator,), dict(bl_idname=name, bl_label=name+&amp;quot;!&amp;quot;, bl_description=name))&lt;br /&gt;
    setattr(my_class, 'invoke', invoke)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
When you try to run the operator you get the error: &amp;quot;invalid operator call&amp;quot;. The reason is that the automatic registering (the metaclass) is done immediately upon creating the class. So right after the line &amp;quot;my_class = type(...)&amp;quot;. Adding methods or attributes after that, for example using setattr(), is too late. So the main thing to remember is:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;setattr() doesn't work with the automatic registration of operators.&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Below are two ways of doing it correctly:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import bpy&lt;br /&gt;
&lt;br /&gt;
my_names = [&amp;quot;Foo&amp;quot;, &amp;quot;Bar&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
def my_invoke(self, context, event):&lt;br /&gt;
    print(self.bl_description)&lt;br /&gt;
    return{'FINISHED'}&lt;br /&gt;
&lt;br /&gt;
for name in my_names:&lt;br /&gt;
    class my_class(bpy.types.Operator):&lt;br /&gt;
        bl_idname = name&lt;br /&gt;
        bl_label = name+&amp;quot;!&amp;quot;&lt;br /&gt;
        bl_description = name&lt;br /&gt;
        invoke = my_invoke&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
import bpy&lt;br /&gt;
&lt;br /&gt;
my_names = [&amp;quot;Foo&amp;quot;, &amp;quot;Bar&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
for name in my_names:&lt;br /&gt;
    class my_class(bpy.types.Operator):&lt;br /&gt;
        bl_idname = name&lt;br /&gt;
        bl_label = name+&amp;quot;!&amp;quot;&lt;br /&gt;
        bl_description = name&lt;br /&gt;
        &lt;br /&gt;
        def invoke(self, context, event):&lt;br /&gt;
            print(self.bl_description)&lt;br /&gt;
            return{'FINISHED'}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is one final thing that might stop your script from working, and that's when the script is run as add-on. In your add-on you can't create operators from within the register() function.&amp;lt;br&amp;gt;&lt;br /&gt;
Example of code that fails when run as add-on (but works correctly when run from the text-editor):&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
bl_addon_info = {&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;FooBar&amp;quot;,&lt;br /&gt;
    &amp;quot;category&amp;quot;: &amp;quot;System&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
import bpy&lt;br /&gt;
&lt;br /&gt;
def create_ops():&lt;br /&gt;
    my_names = [&amp;quot;Foo&amp;quot;, &amp;quot;Bar&amp;quot;]&lt;br /&gt;
    for name in my_names:&lt;br /&gt;
        class my_class(bpy.types.Operator):&lt;br /&gt;
            bl_idname = name&lt;br /&gt;
            bl_label = name+&amp;quot;!&amp;quot;&lt;br /&gt;
            bl_description = name&lt;br /&gt;
            &lt;br /&gt;
            def invoke(self, context, event):&lt;br /&gt;
                print(self.bl_description)&lt;br /&gt;
                return{'FINISHED'}&lt;br /&gt;
    &lt;br /&gt;
def register():&lt;br /&gt;
    create_ops()&lt;br /&gt;
&lt;br /&gt;
def unregister():&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
    register()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The solution is to simply create the operator classes in the module itself (this way they are defined when the module is imported), not in a function definition:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
bl_addon_info = {&lt;br /&gt;
    &amp;quot;name&amp;quot;: &amp;quot;FooBar&amp;quot;,&lt;br /&gt;
    &amp;quot;category&amp;quot;: &amp;quot;System&amp;quot;}&lt;br /&gt;
&lt;br /&gt;
import bpy&lt;br /&gt;
&lt;br /&gt;
my_names = [&amp;quot;Foo&amp;quot;, &amp;quot;Bar&amp;quot;]&lt;br /&gt;
for name in my_names:&lt;br /&gt;
    class my_class(bpy.types.Operator):&lt;br /&gt;
        bl_idname = name&lt;br /&gt;
        bl_label = name+&amp;quot;!&amp;quot;&lt;br /&gt;
        bl_description = name&lt;br /&gt;
           &lt;br /&gt;
        def invoke(self, context, event):&lt;br /&gt;
            print(self.bl_description)&lt;br /&gt;
            return{'FINISHED'}&lt;br /&gt;
    &lt;br /&gt;
def register():&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
def unregister():&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
*Don't use setattr() to set the poll/invoke/execute functions.&lt;br /&gt;
*Don't create operators from within the register() function.&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
== References ==&lt;br /&gt;
[http://lists.blender.org/pipermail/bf-committers/2010-September/028703.html Discussion on the mailinglist]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://svn.blender.org/svnroot/bf-extensions/trunk/py/scripts/addons/space_view3d_copy_attributes.py Correct link to script mentioned in above discussion]&lt;br /&gt;
&lt;br /&gt;
{{Page/Footer|Dev:2.5/Py/API/Overview|}}&lt;/div&gt;</summary>
		<author><name>wiki&gt;Mindrones</name></author>
		
	</entry>
</feed>