首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我应该如何在python中使用闭包创建属性?

我应该如何在python中使用闭包创建属性?
EN

Stack Overflow用户
提问于 2018-06-06 23:17:14
回答 1查看 133关注 0票数 0

我正在使用PyMel为Maya编写一些代码,并尝试在我的rig类中创建一些属性来包装一些PyMel代码。所有属性的代码都非常相似,所以我认为这将是一个使用闭包的好地方。

代码语言:javascript
复制
import pymel.core as pm
import riggermortis.utils as utils

class RigModule(object):
    def __init__:
        # blah blah irrelevant code here
        pass

    def createRootProperty(attrName):
        def getter(self):
            return pm.getAttr(self.root+'.'+attrName)
        def setter(self, nodeToLink):
            if self.root.hasAttr(attrName):
                pm.setAttr(self.root+'.'+attrName, nodeToLink)
            else:
                utils.linkNodes(self.root, nodeToLink, attrName)
        return property(fget=getter,fset=setter)

    hookConstraint = createRootProperty('hookConstraint')
    unhookTarget = createRootProperty('unhookTarget')
    moduleGrp = createRootProperty('moduleGrp')
    hookGrp = createRootProperty('hookGrp')

它在功能上是有效的,但是Eclipse/PyDev告诉我,我的'createRootProperty‘函数需要'self’作为它的第一个参数,所以我想知道我所做的是不是不正确。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-07 05:14:05

对于您正在做的事情,除了干净之外,并不真正需要闭包。linter认为它是一个格式不正确的成员函数,即使它正在执行您想要的操作。

您只需移动类作用域的函数,linter就会停止抱怨--您可以使用下划线重命名函数,这样就不会有人意外地认为它是一个工具而不是一块基础设施。

如果您希望经常这样做,您可以将其自动化到一个元类中,该元类从class字段中读取名称列表,并根据需要创建属性。该策略here有一个更详细的示例,但本质上,元类将在定义类时获得类字典的副本,并且它有机会在编译之前扰乱定义。您可以在该步骤中轻松创建属性:

代码语言:javascript
复制
def createRootProperty(name):
    # this is a dummy, but as long as
    # the return from this function
    # is a property descriptor you're good
    @property
    def me(self):
        return name, self.__class__

    return me


class PropertyMeta(type):

    # this gets called when a class using this meta is
    # first compiled.  It gives you a chance to intervene
    # in the class creation project

    def __new__(cls, name, bases, properties):
        # if the class has a 'PROPS' member, it's a list 
        # of properties to add
        roots = properties.get('PROPS', [])
        for r in roots:
            properties[r] = createRootProperty(r)
            print ("# added property '{}' to {}".format(r, name))

        return type.__new__( cls, name, bases, properties)


class RigModule(object):
    __metaclass__ = PropertyMeta
    PROPS = ['arm', 'head', 'leg']

    def __init__(self):
        pass

test = RigModule()
print test.arm

class Submodule(RigModule):
    # metaclass added properties are inheritable
    pass


test2 = Submodule()
print test2.leg

class NewProperties(RigModule):
    # they can also be augmented in derived classes
    PROPS = ['nose', 'mouth']

print NewProperties().nose
print NewProperties().arm


# added property 'arm' to RigModule
# added property 'head' to RigModule
# added property 'leg' to RigModule
#  ('arm', <class '__main__.RigModule'>)
#  ('leg', <class '__main__.Submodule'>)
# added property 'nose' to NewProperties
# added property 'mouth' to NewProperties
# ('nose', <class '__main__.NewProperties'>)
# ('arm', <class '__main__.NewProperties'>)

元类因为增加了复杂性而得到了不好的评价--有时这是理所当然的。当一种更简单的方法可以使用时,不要使用它们。但是在这种情况下,对于样板文件的减少,它们是一个很好的工具。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50723957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档