2015-03-31 3 views
1

Являются ли функции способными иметь двойные имена для своих аргументов в Python? Я имею в виду короткую и полную форму имени переменной.Псевдонимы в именах аргументов функции (двойное именование)

Я постараюсь быть более ясным. Все, кто знаком с Autodesk Maya, знают функцию для создания ограничений. Он имеет некоторые флаги, и вы можете использовать короткий или длинную форму его имя:

maintainOffset (МО), вес (масса), слой (л) и так далее ..

Так вы можете вызвать эту функцию с разными именами, это аргументы, но это дает тот же результат:

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() с этими значениями по умолчанию

ответ

0
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) 

Я привык делать это в некоторых из моих сценариев

EDIT ---

Если у вас есть на это несколько раз, это может быть легко создать пользовательский класс:

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 
+0

спасибо, например – Michael

3

Если я правильно понял, что вы после этого, самый простой способ сделать это это с **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 
+0

Я действительно никогда не делаю декораторов, но должен 'wrapper' быть' wrapper (* args, ** kwargs) ', а оператор return -' return func (* args, ** kwargs) '? –

+0

@StevenRumbalski да, это было бы необходимо, чтобы поддержать любые позиционные аргументы, но я думал, что это будет только мутная вода на этом этапе. – jonrsharpe

+0

Jonrsharpe Мне нужно время, чтобы подумать о ваших словах и попытаться реализовать свою идею! – Michael

 Смежные вопросы

  • Нет связанных вопросов^_^