有没有办法缩进Python而不影响代码

Pet*_*ter 2 python maya pymel

我正在尝试在Maya中编写一个用户界面,并且它会让父母的多个级别变得令人难以置信,并且没有缩进.基本代码(没有任何功能)目前大约有400行,需要一段时间才能找到我需要的位.

例如,在没有注释的情况下使用以下代码

#Earlier user interface

py.rowColumnLayout( numberOfColumns = 5 )
py.text( label="", width = 1 )
py.text( label="Column 1", enable = False, width = 250 )
py.text( label="", width = 1 )
py.text( label="Column 2" enable = False, width = 250 )
py.text( label="", width = 1 )

py.text( label="" )
py.rowColumnLayout( numberOfColumns = 4 )
py.text( label="   Input data:", align="left" )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.textField( text = "Text here" )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.setParent( ".." )

py.text( label="" )
py.rowColumnLayout( numberOfColumns = 4 )
py.rowColumnLayout( numberOfColumns = 5 )
py.radioButton( label = "Read file from path", width = 100 )
py.text( label="" )
py.button( label = "Browse" )
py.text( label="" )
py.button( label = "Validate" )
py.setParent( ".." )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.setParent( ".." )
py.setParent( ".." )
Run Code Online (Sandbox Code Playgroud)

但是,这就是缩进的外观

py.rowColumnLayout( numberOfColumns = 5 )
    py.text( label="", width = 1 )
    py.text( label="Column 1", enable = False, width = 250 )
    py.text( label="", width = 1 )
    py.text( label="Column 2" enable = False, width = 250 )
    py.text( label="", width = 1 )

    py.text( label="" )
    py.rowColumnLayout( numberOfColumns = 4 )
        py.text( label="   Input data:", align="left" )
        py.text( label="" )
        py.text( label="" )
        py.text( label="" )
        py.textField( text = "Text here" )
        py.text( label="" )
        py.text( label="" )
        py.text( label="" )
        py.setParent( ".." )

    py.text( label="" )
    py.rowColumnLayout( numberOfColumns = 4 )
        py.rowColumnLayout( numberOfColumns = 5 )
            py.radioButton( label = "Read file from path", width = 100 )
            py.text( label="" )
            py.button( label = "Browse" )
            py.text( label="" )
            py.button( label = "Validate" )
            py.setParent( ".." )
        py.text( label="" )
        py.text( label="" )
        py.text( label="" )
        py.setParent( ".." )
    py.setParent( ".." )
Run Code Online (Sandbox Code Playgroud)

有什么办法我可以用缩进写它但是让它在执行时忽略它们吗?我看到了一个问题,问你是否可以在没有缩进的情况下编写python,但我有点需要相反的东西.

注意:某些py.*函数的输出值也需要分配给变量,因为布局需要先排序,所以还没有.

kar*_*kg3 6

这是一个很好的用例,像我们这样的技术艺术家每天都会在Maya中构建UI.

对于基于PyMEL的UI:

这内置于PyMEL中.您不必创建上下文管理器.布局命令本身是上下文管理器.您只需with在每次布局命令调用之前添加关键字,如下所示:

# Do this when using PyMEL for your UI code
import pymel.core as pm

# ...

with pm.rowColumnLayout( numberOfColumns = 5 ):
    pm.text( label="", width = 1 )
    pm.text( label="Column 1", enable = False, width = 250 )
    pm.text( label="", width = 1 )
    pm.text( label="Column 2", enable = False, width = 250 )
    pm.text( label="", width = 1 )

    pm.text( label="" )

    with pm.rowColumnLayout( numberOfColumns = 4 ):
        pm.text( label="   Input data:", align="left" )
        pm.text( label="" )
        pm.text( label="" )
        pm.text( label="" )
        pm.textField( text = "Text here" )
        pm.text( label="" )
        pm.text( label="" )
        pm.text( label="" )        

    pm.text( label="" )
    with pm.rowColumnLayout( numberOfColumns = 4 ):
        with pm.rowColumnLayout( numberOfColumns = 5 ):
            pm.radioButton( label = "Read file from path", width = 100 )
            pm.text( label="" )
            pm.button( label = "Browse" )
            pm.text( label="" )
            pm.button( label = "Validate" )

        pm.text( label="" )
        pm.text( label="" )
        pm.text( label="" )
Run Code Online (Sandbox Code Playgroud)

对于基于maya.cmds的UI:

一个快速的解决方案是创建一个虚拟上下文管理器.你可以这样做

# Do this when using Maya's cmds for your UI code
import maya.cmds as cmds

# ...

from contextlib import contextmanager
@contextmanager
def neat_indent():
    # OPTIONAL: This is also an opportunity to do something before the block of code runs!
    try:
        # During this is where your indented block will execute
        # Leave it empty
        yield
    finally:
        # OPTIONAL: This is where you can write code that executes AFTER your indented block executes.
        pass
Run Code Online (Sandbox Code Playgroud)

这样你的代码就不必改变太多了.只需with在每个意图缩进的开头添加关键字的上下文管理器功能!

cmds.rowColumnLayout( numberOfColumns = 5 )
with neat_indent():
    cmds.text( label="", width = 1 )
    cmds.text( label="Column 1", enable = False, width = 250 )
    cmds.text( label="", width = 1 )
    cmds.text( label="Column 2", enable = False, width = 250 )
    cmds.text( label="", width = 1 )

    cmds.text( label="" )

    cmds.rowColumnLayout( numberOfColumns = 4 )
    with neat_indent():
        cmds.text( label="   Input data:", align="left" )
        cmds.text( label="" )
        cmds.text( label="" )
        cmds.text( label="" )
        cmds.textField( text = "Text here" )
        cmds.text( label="" )
        cmds.text( label="" )
        cmds.text( label="" )
        cmds.setParent( ".." )

    cmds.text( label="" )
    cmds.rowColumnLayout( numberOfColumns = 4 )
    with neat_indent():
        cmds.rowColumnLayout( numberOfColumns = 5 )
        with neat_indent():
            cmds.radioButton( label = "Read file from path", width = 100 )
            cmds.text( label="" )
            cmds.button( label = "Browse" )
            cmds.text( label="" )
            cmds.button( label = "Validate" )
            cmds.setParent( ".." )
        cmds.text( label="" )
        cmds.text( label="" )
        cmds.text( label="" )
        cmds.setParent( ".." )
    cmds.setParent( ".." )
Run Code Online (Sandbox Code Playgroud)

我们创建的上下文管理器neat_indent()也让您有机会编写包装缩进块的代码.这里的一个实际例子是,在每个缩进的最后,你发现自己在写作py.setParent("..").您可以将其放入finally上下文管理器的部分:

from contextlib import contextmanager
@contextmanager
def neat_indent(parent=None):
    # OPTIONAL: This is also an opportunity to do something before the block of code runs!
    try:
        # During this is where your indented block will execute
        # Leave it empty
        yield
    finally:
        # OPTIONAL: This is where you can write code that executes AFTER your indented block executes.
        if parent:
            cmds.setParent(parent)
Run Code Online (Sandbox Code Playgroud)

你的代码现在更有意义了:

cmds.rowColumnLayout( numberOfColumns = 5 )
with neat_indent(".."):
    cmds.text( label="", width = 1 )
    cmds.text( label="Column 1", enable = False, width = 250 )
    cmds.text( label="", width = 1 )
    cmds.text( label="Column 2", enable = False, width = 250 )
    cmds.text( label="", width = 1 )

    cmds.text( label="" )

    cmds.rowColumnLayout( numberOfColumns = 4 )
    with neat_indent(".."):
        cmds.text( label="   Input data:", align="left" )
        cmds.text( label="" )
        cmds.text( label="" )
        cmds.text( label="" )
        cmds.textField( text = "Text here" )
        cmds.text( label="" )
        cmds.text( label="" )
        cmds.text( label="" )        

    cmds.text( label="" )
    cmds.rowColumnLayout( numberOfColumns = 4 )
    with neat_indent(".."):
        cmds.rowColumnLayout( numberOfColumns = 5 )
        with neat_indent(".."):
            cmds.radioButton( label = "Read file from path", width = 100 )
            cmds.text( label="" )
            cmds.button( label = "Browse" )
            cmds.text( label="" )
            cmds.button( label = "Validate" )

        cmds.text( label="" )
        cmds.text( label="" )
        cmds.text( label="" )
Run Code Online (Sandbox Code Playgroud)

上下文管理器很强大.在这篇文章中,我使用了标准库模块中的contextmanager 装饰器contextlib.你可以在这里阅读这个技术.关于这里with一般.

此外,为了达到这个目的(其中一个目的),在Maya中进行UI开发更清洁,更多Pythonic @theodox创建了mGui模块.看看这个.