函数参数名称中的别名(双重命名)
Aliasing in the names of function arguments (double naming)
Python 中的函数是否可以为其参数使用双名?
我的意思是变量名的简短完整形式。
我会尽量说得更清楚。熟悉 Autodesk Maya 的人都知道
一个做约束的函数。它有一些标志,您可以使用其名称的短形式或长形式:
maintainOffset(mo), weight(w), layer(l) and so on..
所以你可以用不同的参数名称调用这个函数,但它给你相同的结果:
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,..)
如何在Python2.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)
以及某种 wrapper 函数用于所有这些:
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() 这些默认值
如果我正确理解了您的要求,最简单的方法是使用 **kwargs
"magic" 和 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
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 :
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
Python 中的函数是否可以为其参数使用双名? 我的意思是变量名的简短完整形式。
我会尽量说得更清楚。熟悉 Autodesk Maya 的人都知道 一个做约束的函数。它有一些标志,您可以使用其名称的短形式或长形式:
maintainOffset(mo), weight(w), layer(l) and so on..
所以你可以用不同的参数名称调用这个函数,但它给你相同的结果:
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,..)
如何在Python2.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)
以及某种 wrapper 函数用于所有这些:
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() 这些默认值
如果我正确理解了您的要求,最简单的方法是使用 **kwargs
"magic" 和 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
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 :
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