【问题标题】:How to replace individual strings in a list with variables?如何用变量替换列表中的单个字符串?
【发布时间】:2014-11-20 17:58:46
【问题描述】:

我正在编写一个脚本,以便在 python 中为程序 maya 制定命名约定。 我将使用它来命名我的脚本创建的所有对象。

例如,让我们以左膝关节为例。该脚本将通过类似这样的东西 ("bind", "shoulder", "left", "joint") 到另一个模块中的变量 (前缀、名称、边、obj_type)。然后,此输入将通过用户字典运行以检查现有值并更改为新值,如果未找到任何内容,则返回原始值。例如,“join”会变成“jnt”。

用户将输入类似 (prefix_,name_,SIDE_,obj_type,01) 的内容

我需要它,以便它检查用户输入中的任何内容是否存在于变量名中。例如,如果它在用户输入中找到任何变量名称(例如“前缀”),则将变量前缀中包含的任何内容替换为它所在位置的索引处。此外,字符串中未找到的任何内容都将被单独保留,例如“01”,它将简单地添加到每个名称中。

例如,上面的代码会返回这个“bn_shoulder_L_jnt01”

此外,如果某些内容是大写的,例如第一个字母或所有字母,我希望它自动将传递的字母大写。这就是为什么键入 SIDE_ 会将“l”变成“L”。

我希望它尽可能灵活,但我目前的麻烦是让它在找到值时将变量替换为现有字符串。我试着想了几件事,但没有想出太多。这是我的代码:

另外,我目前将用户输入传递给 init 中的类。它会在整个模块中工作并可用吗?我仍然不能 100% 确定应该如何使用 init,但我希望当用户输入命名约定时,它会在需要时在内存中可用。

编辑代码:

from string import Template

class Name:

    def __init__(self, user_conv):
        self.user_conv = user_conv


    def user_dict(self, word):
        """Matches given word with a dictionary, and returns converted abbreviated word.

        Keyword Arguments:
        string -- given string to be converted
                  example: joint > jnt
        """

        # prefixes
        user_library = {
        'bind' : 'bn',
        'driver' : 'drv',

        # side
        'back' : 'b',
        'down' : 'd',
        'front' : 'f',
        'left' : 'l',
        'right' : 'r',
        'up' : 'u',

        # obj_type
        'cluster' : 'clstr',
        'control' : 'ctrl',
        'curve' : 'crv',
        'effector' : 'efctr',
        'group' : 'grp',
        'ikHandle' : 'ikH',
        'joint' : 'jnt',
        'locator' : 'loc',
        'nurbs' : 'geo',
        'orientConstraint' : 'orCnstr',
        'parentConstraint' : 'prntCnstr',
        'pointConstraint' : 'ptCnstr',
        'polyMesh' : 'geo',

        # utilities
        'addDoubleLinear' : 'adl',
        'blendColors' : 'blndClr',
        'BlendTwoAttr' : 'b2a',
        'chooser' : 'chsr',
        'clamp' : 'clmp',
        'condition' : 'cn',
        'curveInfo' : 'crvI',
        'diffuse' : 'diffuse',
        'displacement' : 'displ',
        'multiplyDivide' : 'mdv',
        'normal' : 'normal',
        'place2d' : 'p2d',
        'plusMinusAverage' : 'pma',
        'reverse' : 'rv',
        'setRange' : 'sr',
        'shader' : 'shdr',
        'shadingGroup' : 'SG',
        'specular' : 'spec',
        'transparency' : 'trans',

        # sequential bones
        'arm' : 'arm',
        'fingser' : 'finger',
        'index' : 'index',
        'leg' : 'leg',
        'limb' : 'limb',
        'middle' : 'middle',
        'pinky' : 'pinky',
        'ring' : 'ring',
        'spine' : 'spine',
        'toe' : 'toe',
        'thumb' : 'thumb',

        #
        'ankle' : 'ankle',
        'ball' : 'ball',
        'breast' : 'breast',
        'chest' : 'chest',
        'clavicle' : ' clavicle',
        'elbow' : 'elbow',
        'end' : 'e',
        'head' : 'head',
        'hair' : 'hair',
        'knee' : 'knee',
        'neck' : 'neck',
        'pelvis' : 'pelvis',
        'root' : 'root',
        'shoulder' : 'shoulder',
        'tail' : 'tail',
        'thigh' : 'thigh',
        'wrist' : 'wrist'
        }

        if word in user_library:
            abbrevWord = user_library[word]
        else:
            abbrevWord = word

        return [abbrevWord]

    def convert(self, prefix, name, side, obj_type):
        """Converts given information about object into user specified naming convention.

        Keyword Arguments:
        prefix -- what is prefixed before the name
        name -- name of the object or node
        side -- what side the object is on, example 'left' or 'right'
        obj_type -- the type of the object, example 'joint' or 'multiplyDivide'
        """
        self.prefix = self.user_dict(prefix)
        self.name = self.user_dict(name)
        self.side = self.user_dict(side)
        self.obj_type = self.user_dict(obj_type)

        print '%s, %s, %s, %s' %(prefix, name, side, obj_type)

        self.new_string = Template (self.user_conv.lower())
        self.subs = {'prefix': prefix, 'name': name, 'side': side, 'obj_type': obj_type}
        self.new_string.substitute(**self.subs)

        print new_string

        return new_string

test code:

    # test file to test naming convention to see if its functioning properly

    import neo_name
    reload(neo_name)

def ui_test():
    """types user can input
    #prefix
    #name
    #side
    #type
    constants (such as 01, present in ALL objects/nodes/etc.)
    """
    user_conv = '${prefix}_${name}_${side}_${obj_type}${01}'

    name = neo_name.Name(user_conv)
    name.convert('bind', 'shoulder', 'left', 'joint')

ui_test()

现在遇到这个错误,不知道是怎么回事: 绑定, 肩, 左, 关节 回溯(最近一次通话最后): 文件“C:\Users\Gregory\Documents\Gregory's Folder\Artwork\3D Scripts_MyScripts\neoAutoRig\scripts\test_neo_name.py”,第 19 行,在 ui_test() 文件“C:\Users\Gregory\Documents\Gregory's Folder\Artwork\3D Scripts_MyScripts\neoAutoRig\scripts\test_neo_name.py”,第 17 行,在 ui_test name.convert('绑定', '肩', '左', '关节')

文件“C:\Users\Gregory\Documents\Gregory's Folder\Artwork\3D Scripts_MyScripts\neoAutoRig\scripts\neo_name.py”,第 133 行,转换中 self.new_string.substitute(前缀 = 前缀,名称 = 名称,边 = 边,obj_type = obj_type) 文件“C:\Program Files\Autodesk\Maya2014\bin\python27.zip\string.py”,第 172 行,代替 文件“C:\Program Files\Autodesk\Maya2014\bin\python27.zip\string.py”,第 169 行,在转换中 _invalid 中的文件“C:\Program Files\Autodesk\Maya2014\bin\python27.zip\string.py”,第 146 行 ValueError:字符串中的占位符无效:第 1 行,第 38 列

【问题讨论】:

  • 您的实际问题是什么?目前尚不清楚您在哪里遇到问题。

标签: python list replace maya


【解决方案1】:

这也是pythonstring.Template类的好应用:

从字符串导入模板

t = Template ("${prefix}_${side}_${limb}")
t.substitute(prefix ='character', side='R', limb='hand')
>>> 'character_R_hand'

您可以通过将分隔符视为条件(默认为 '')、强制大写规则等来获得更好的体验。 Template.substitute 采用标志(如上例所示)或字典:

t = Template ("${prefix}_${side}_${limb}")
subs = {'prefix':'dict', 'side':'L', 'limb':'bicep'}
t.substitute(**subs)
>>> 'dict_L_hand'

【讨论】:

  • 谢谢,这正是我想要的!
  • 虽然现在我得到一个值错误,但我会在上面发布详细信息,并编辑代码。
  • 可能是您提供的密钥与占位符中的字符串不匹配的错字。如果您改用safe_substitute,则不会出现错误:相反,您会在输出中看到未填写的占位符\
  • 谢谢!基本的东西现在运行起来了,将用 CAPS 扩展它,这是一种让用户轻松输入的好方法。
【解决方案2】:

你必须制作一个字典,将你的字符串映射到实际的命令

d = {'bind':'bn', 'left':'L', 'joint':'jnt'}
l = ['bind', 'shoulder', 'left', 'joint', '01']

然后使用带有第二个参数的get,如果它没有找到那个键,你可以只传递原始参数。然后将所有内容与'_' 连接在一起。

'_'.join(d.get(i,i) for i in l)

输出

'bn_shoulder_L_jnt_01'

在你的情况下,这将是

'_'.join(userLibrary.get(word,word) for word in prefixes)

【讨论】:

    猜你喜欢
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    • 2021-08-03
    • 2011-10-23
    相关资源
    最近更新 更多