Dieser Artikel ist ein Artikel vom 20. Dezember des Maya-Python-Adventskalenders 2016.
In maya.cmds können Sie das Flag, das an den Befehl übergeben werden soll, auf zwei Arten schreiben: ** Kurznamen-Notation ** und ** Langnamen-Notation **. Wenn Sie beispielsweise den Befehl maya.cmds.optionMenu verwenden, um Prozesse mit derselben Bedeutung in Kurz- und Langnamen zu schreiben, sieht dies folgendermaßen aus.
#Kurzname Notation
cmds.optionMenu(name, en=True, l="top_node:",
vis=True, ann=u"Wählen Sie den obersten Knoten aus", w=200,
cc=partial(self.change_topnode, name))
#Langname Notation
cmds.optionMenu(name, enable=True, label="top_node:",
visible=True, annotation=u"Wählen Sie den obersten Knoten aus", width=200,
changeCommand=partial(self.change_topnode, name))
Die Kurznamen-Notation macht den Code kompakter, daher ist er möglicherweise besser für diejenigen, die daran gewöhnt sind. Für maya.cmds-Anfänger wie mich wird jedoch jedes Mal, wenn beim Erben oder Überprüfen von Code, der von einer anderen Person geschrieben wurde, ein Kurznamen-Flag angezeigt wird, [Autodesks Maya Python-Befehlsreferenz](http: // help) .autodesk.com / cloudhelp / 2016 / JPN / Maya-Tech-Docs / CommandsPython / index.html) ist ineffizient.
Daher werden wir dieses Mal ein Skript erstellen, das das Kurznamen-Notationsflag sofort durch das Langnamen-Notationsflag ersetzt.
Der Betrieb des Programms wurde in der folgenden Umgebung bestätigt.
Es ist nur ein externes Modul namens astor erforderlich. Installieren Sie es daher mit pip.
pip install astor
AST (Abstract Syntax Tree) wird verwendet, um die Parameternamen zu analysieren und zu ersetzen, die beim Aufrufen der Funktion maya.cmds verwendet werden. Mit dem im Python-Standard enthaltenen ast-Modul können Sie einen AST erhalten, indem Sie einfach den Code analysieren, den Sie analysieren möchten.
import ast
if __name__ == '__main__':
example = """def fake(x):
import maya.cmds as cmds
cmds.optionMenu(name, q=True, v=True)
return 0
"""
tree = ast.parse(example)
print ast.dump(tree)
Wenn das obige Programm ausgeführt wird, wird das folgende Ergebnis ausgegeben.
Module(body=[FunctionDef(name='fake', args=arguments(args=[Name(id='x', ctx=Param())],
vararg=None, kwarg=None, defaults=[]), body=[Import(names=[alias(name='maya.cmds',
asname='cmds')]), Expr(value=Call(func=Attribute(value=Name(id='cmds', ctx=Load()),
attr='optionMenu', ctx=Load()), args=[Name(id='name', ctx=Load())],
keywords=[keyword(arg='q', value=Name(id='True', ctx=Load())), keyword(arg='v',
value=Name(id='True', ctx=Load()))], starargs=None, kwargs=None)),
Return(value=Num(n=0))], decorator_list=[])])
Es ist ein bisschen lang und schwer zu lesen, aber hier
Es ist wichtig, dass Sie Informationen über die Region erhalten. Mit anderen Worten, Sie können sehen, welcher Befehl in maya.cmds mit welchem Flag-Argument ausgeführt wird.
Nachdem wir nun wissen, dass wir mit AST herausfinden können, ob die Kurznamen-Notation im Code verwendet wird, besteht der nächste Schritt darin, die Entsprechungstabelle zwischen der Kurznamen-Notation und der Langnamen-Notation in jeder maya.cmds abzurufen. Wenn Sie den Befehlsnamen an maya.cmds.help () übergeben, werden die Kurznamen- und Langnamen-Notation wie unten gezeigt zurückgegeben.
import maya.cmds
print(maya.cmds.help("optionMenu"))
-----------------------------------------------------
einpacken: optionMenu [flags] [String]
Flags:
-e -edit
-q -query
-acc -alwaysCallChangeCommand
-ann -annotation String
-bgc -backgroundColor Float Float Float
-cc -changeCommand Script
...(Kürzung)
Generieren Sie dynamisch ein Diktat mit der Kurznamen-Notation als Schlüssel und der Langnamen-Notation als Wert unter Verwendung regulärer Ausdrücke.
help_regex.py
method_name_dict = {}
help_messages = cmds.help(method_name)
method_name_dict[method_name] = {}
for line in help_messages.split(os.linesep):
arg_names = re.search(r"-([a-zA-Z0-9]+) -([a-zA-Z0-9]+)", line)
if arg_names:
method_name_dict[method_name][arg_names.group(1)] = arg_names.group(2)
Sie können ein Diktierobjekt wie dieses erstellen
[('optionMenu', {u'en': u'enable', u'cc': u'changeCommand', u'm': u'manage', u'ann': u'annotation', ...(Kürzung)
Der Befehl maya.cmds.help () muss jedoch in der Python-Ausführungsumgebung von maya ausgeführt werden. (Normalerweise wird mit Python aaa.py nichts zurückgegeben.)
Für Mac
/Applications/Autodesk/maya2015/Maya.app/Contents/bin/mayapy
Für Windows
C:\Program Files\Autodesk\Maya2015\bin\mayapy.exe
Es gibt Mayapy. Wenn Sie also ein Python-Programm damit ausführen, erhalten Sie das Ergebnis des Befehls help ().
/Applications/Autodesk/maya2015/Maya.app/Contents/bin/mayapy aaa.py
Jetzt können Sie den Kurznamen durch den Langnamen ersetzen.
Verwenden Sie NodeTransformer, um jedes Element des AST zu überprüfen, zu ersetzen oder zu löschen. Wenn Sie beispielsweise wie folgt etwas mit dem Funktionsaufrufknoten (Call) tun möchten, definieren Sie die Funktion visit_Call (self, node) und schreiben Sie den Prozess.
class MayaPythonShort2LongNameNodeTransformer(ast.NodeTransformer):
def visit_Call(self, node):
#Ich werde den Austauschprozess hier schreiben
Nachdem Sie den Flag-Namen durch NodeTransformer ersetzt haben, kehren Sie schließlich mit astor.to_source () zum Python-Code zurück.
print(astor.to_source(tree).decode("unicode-escape"))
Der folgende Code ist eine angemessene Zusammenfassung der obigen Verarbeitung.
maya_cmds_name_converter.py
# -*- coding: utf-8 -*-
from __future__ import absolute_import, division, print_function, unicode_literals
import os
import re
import ast
import astor
import maya.standalone
import maya.cmds as cmds
class MayaPythonShort2LongNameNodeTransformer(ast.NodeTransformer):
def __init__(self):
self.method_name_dict = {}
@staticmethod
def is_maya_cmds_func(node):
return hasattr(node, "func") and hasattr(node.func, "value") and hasattr(node.func.value, "id") and \
node.func.value.id == "cmds"
def visit_Call(self, node):
if self.is_maya_cmds_func(node):
method_name = node.func.attr
if not self.method_name_dict.get(method_name):
# short_Name und lang_Erstellen Sie ein entsprechendes Diktat für den Namen
try:
help_messages = cmds.help(method_name)
except RuntimeError:
# print(u"help()Ist ein nicht unterstützter Befehl: " + method_name)
return node
self.method_name_dict[method_name] = {}
for line in help_messages.split(os.linesep):
arg_names = re.search(r"-([a-zA-Z0-9]+) -([a-zA-Z0-9]+)", line)
if arg_names:
self.method_name_dict[method_name][arg_names.group(1)] = arg_names.group(2)
for keyword in node.keywords:
if keyword.arg in {"q", "e", "c", "m"}:
#Ignorieren, wenn Basisflag
continue
long_name = self.method_name_dict[method_name].get(keyword.arg)
if long_name:
if long_name == "import":
#In diesem Fall wird es seltsam wie Python
continue
# print(keyword.arg + u"Zu" + long_name + u"Konvertieren zu")
keyword.arg = long_name
return node
if __name__ == '__main__':
maya.standalone.initialize(name='python')
#Beispielcode zum Testen
example = """def fake(x):
import maya.cmds as cmds
cmds.optionMenu(name, en=True, l="top_node:",
vis=True, ann=u"Wählen Sie den obersten Knoten aus", w=200,
cc=partial(self.change_topnode, name))
return top_node
"""
tree = ast.parse(example)
tree = MayaPythonShort2LongNameNodeTransformer().visit(tree)
# after convert python code
print(astor.to_source(tree).decode("unicode-escape"))
if float(cmds.about(v=True)) >= 2016:
maya.standalone.uninitialize()
Wenn dieses Programm ausgeführt wird, wird der Befehl des zu Beginn eingeführten Kurznamen-Notationsflags durch die Langnamen-Notation und -Ausgabe ersetzt.
Vor dem Austausch
def fake(x):
import maya.cmds as cmds
cmds.optionMenu(name, en=True, l="top_node:",
vis=True, ann=u"Wählen Sie den obersten Knoten aus", w=200,
cc=partial(self.change_topnode, name))
return top_node
Nach dem Austausch
def fake(x):
import maya.cmds as cmds
cmds.optionMenu(name, enable=True, label='top_node:', visible=True, annotation=u'Wählen Sie den obersten Knoten aus', width=200, changeCommand=partial(self.change_topnode, name))
return top_node
Es schien zu funktionieren, aber nachdem ast.parse den Python-Code, wenn ich ihn mit astor.to_source () wieder in den Python-Code konvertiere, verliere ich viele Formatierungsinformationen.
--u "" "Dies ist eine Dokumentationszeichenfolge" "" ist alles u \ Dies ist eine Dokumentationszeichenfolge \
Nachdem ich Kurznamen-> Langnamen ersetzt habe, bereinige ich sie separat mit AutoFormatter / Löschen von Warnungen / Ersetzen durch PyCharm. ..
Wenn Sie sich daran gewöhnt haben, ist die Kurznamen-Notation möglicherweise einfacher zu schreiben und zu lesen, aber ich kann mich immer noch nicht an die große Anzahl von Flags erinnern, die in maya.cmds enthalten sind.
Wie erwartet ist l Label, v ist Wert usw., daher halte ich es für eine gute Idee, die Regel des Flaggennamens entsprechend der Kompetenzstufe des am Code beteiligten Teams zu bestimmen. Wenn es sich um ein Flag handelt, das anscheinend nur selten verwendet wird, können Sie die Bedeutung anhand des langen Namens verstehen. Wenn es sich jedoch um einen kurzen Namen handelt, wird definitiv etwas als Befehlsreferenz gesendet. Seien Sie also vorsichtig.
bsp -> beforeShowPopup npm -> numberOfPopupMenus vcc -> visibleChangeCommand Und.
Recommended Posts