函数参数名称中的别名(双命名)

时间:2015-03-31 17:07:40

标签: python constraints batch-processing maya aliasing

函数是否能够在Python中为其参数设置双重名称? 我的意思是变量名称的简短形式。

我会更加清楚。熟悉Autodesk Maya的每个人都知道 一个制约束的函数。它有一些标志,您可以使用它的短名称或长名称:

  

maintainOffset(mo),weight(w),layer(l)等等。

因此,您可以使用不同的名称来调用此函数,但它会给您相同的结果:

cmds.parentConstraint(driverObj, drivenObj, maintainOffset=True, weight=1.0,..)
cmds.parentConstraint(driverObj, drivenObj, maintainOffset=True, w=1.0,..)
cmds.parentConstraint(driverObj, drivenObj, mo=True, weight=1.0,..)
cmds.parentConstraint(driverObj, drivenObj, mo=True, w=True,..)

如何在Python 2.7.x中实现此类行为?我积极使用文档,但仍无法找到答案。

此外,我已为各种类型的约束定义了4个函数:

# Parent Constraint
def doParentConstraint(lst, mo = True, w = 1.0, sr = 'None', st = 'None', l = 'None'):
    for pair in lst:
        cmds.parentConstraint(pair[0], pair[1], maintainOffset = mo, weight = w,
                                skipRotate = sr, skipTranslate = st, layer = l)
# Orient Constraint
def doOrientConstraint(lst, mo = False, w = 1.0, o = (0.0, 0.0, 0.0), sk = 'None', l = 'None'):
    for pair in lst:
        cmds.orientConstraint(pair[0], pair[1], maintainOffset = mo, weight = w, 
                                offset = o, skip = sk, layer = l)
# Point Constraint
def doPointConstraint(lst, mo = False, w = 1.0, o = (0.0, 0.0, 0.0), sk = 'None', l = 'None'):
    for pair in lst:
        cmds.orientConstraint(pair[0], pair[1], maintainOffset = mo, weight = w, 
                                offset = o, skip = sk, layer = l)
# Scale Constraint
def doScaleConstraint(lst, mo = False, w = 1.0, o = (0.0, 0.0, 0.0), sk = 'None', l = 'None'):
    for pair in lst:
        cmds.orientConstraint(pair[0], pair[1], maintainOffset = mo, weight = w, 
                                offset = o, skip = sk, layer = l)

连接列表:

cLst = produceConnectionList(tNodesA, tNodesB)

所有这些的包装函数:

def batchConnect(type = "parentConstraint", ???):
    cLst = produceConnectionList(tNodesA, tNodesB)
    if type is "parentConstraint": doParentConstraint(cLst, ???)
    if type is "orientConstraint": doOrientConstraint(cLst, ???)
    if type is "pointConstraint": doPointConstraint(cLst, ???)
    if type is "scaleConstraint": doScaleConstraint(cLst, ???)

但是我不知道如何在这些函数和包装器之间传递值,因为虽然它们具有相同数量的参数但是参数的名称和那些类型有点不同。

此外,我希望有机会在调用包装器时使用简短和完整形式的标志名称:

batchConnect("pointConstraint", mo=False, offset=(0,0,0), weight=1)
batchConnect("pointConstraint", maintainOffset=False, o=(0,0,0), w=1)

必须这样做。

batchConnect("pointConstraint")

不带参数必须使用默认值调用 doPointConstraint()

batchConnect()

在没有指定类型和参数的情况下,默认情况下必须使用这些默认值调用 doParentConstraint()

2 个答案:

答案 0 :(得分:4)

如果我已经正确理解了您之后所做的事情,最简单的方法就是使用**kwargs"魔法"和dict.get,例如:

def demo(maintain_offset=None, **config):
    if maintain_offset is None:  # if not supplied by 'real name'
        maintain_offset = config.get('mo', 'baz')  # check alias, fall back to default
    print maintain_offset

(请注意遵守style guide。使用中:

>>> demo(maintain_offset="foo")
foo
>>> demo(mo="bar")
bar
>>> demo()
baz

如果不熟悉此语法,请参阅What does ** (double star) and * (star) do for parameters?


对于更通用的方法,您可以使用装饰器语法用一组别名包装函数:

import functools

def alias(aliases):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(**kwargs):
            for name, alias in aliases.items():
                if name not in kwargs and alias in kwargs:
                    kwargs[name] = kwargs[alias]
            return func(**kwargs)
        return wrapper
    return decorator

使用中:

>>> @alias({'maintain_offset': 'mo'})
def demo(maintain_offset='baz', **kwargs):
    print maintain_offset


>>> demo(maintain_offset="foo")
foo
>>> demo(mo="bar")
bar
>>> demo()
baz

答案 1 :(得分:1)

def myExample(**kwargs):
    if kwargs.get("width") and kwargs.get("w"):
        cmds.error("same flag used two times")
    else:
        myWidth = kwargs.get("width") or kwargs.get("w") or "nothing"
    print(myWidth)

myExample(width=200)

我曾经在我的一些剧本中这样做

编辑---

如果您需要多次,可能很容易创建自定义类:

class mimicKwargs:
    def __init__(self, labelLong, labelShort, defautValue,kwargDic):
        if kwargDic.get(labelLong) and kwargDic.get(labelShort):
            cmds.error("same flag used two times")
        else:
            self.userInput = kwargDic.get(labelLong) or kwargDic.get(labelShort) or defautValue
    def output(self):
        return self.userInput

def myExample(**kwargs):

    myWidth = mimicKwargs("width", "w", 150, kwargs).output()

    print(myWidth)

myExample(width=200)#
myExample()#print 150