簡體   English   中英

程序創建的裝飾函數

[英]Procedurally created decorator functions

我的目標是創建一個函數,該函數將在序列化數據的過程中從程序上生成一系列其他函數。 這很容易使用dict ,但是...我想用@property裝飾器(或類似的自定義裝飾器)初始化每個函數,這樣我就可以像屬性一樣調用這些函數

基本上,我想做類似以下的事情:

class myClass(object):
    def __init__(self):
        self.makeFuncs(['edgar','allan','poe'])

    def makeFuncs(self, data):
        for item in data:
            self.__dict__[item] = '[%s] <--- is_the_data' % item 

myInstance = myClass()
print myInstance.poe
#'[poe] <--- is_the_data'

有什么想法?

您可以動態添加property ,但屬性將添加到對象,而不是實例。

這是一個例子:

def make_prop(cls, p):
    def f(self):
        print 'IN %s' % p
        return '[%s]' % p
    return f    

class myClass(object):
  pass

# add the properties
for p in ('edgar','allan','poe'):
    setattr(myClass, p, property(make_prop(myClass, p)))

y = myClass()
print y.a
print y.b

打印:

IN allan
[allan]
IN poe
[poe]

此外,由於python的詞法作用域,必須使用make_prop來創建函數對象,而不是直接在for循環中創建它們。 這不會按預期工作

# add the properties
for p in ('edgar','allan','poe'):
    def f(self):
        print 'IN %s' % p
        return '[%s]' % p
    setattr(myClass, p, property(f))

下面是我為在maya中自定義着色器類的過程添加屬性而給出的答案。

謝謝@ shx2!

import maya.cmds as mc
import sushi.maya.node.dependNode as dep

class Shader(dep.DependNode):
    def __init__(self, *args, **kwargs):
        super(Shader, self).__init__(*args, **kwargs)
        makeProps(self.__class__, ['color','transparency','ambientColor','incandescence','diffuse','translucence','translucenceDepth','translucenceFocus'])

def createShaderProperties(attrName):
    def getterProp(self):
        return mc.getAttr('%s.%s' % (self.name, attrName))[0]
    def setterProp(self, value):
        mc.setAttr('%s.%s' % (self.name, attrName), *value, type = 'double3')
    return (getterProp, setterProp)

def makeProps(cls, data):
    for dat in data:
        getterProp, setterProp = createShaderProperties(dat)
        setattr(cls, dat, property(getterProp))
        setattr(cls, dat, property.setter(cls.__dict__[dat],setterProp))

您當前的想法將無法工作,因為property對象需要在類中才能工作(它們是描述符 )。 由於您的函數列表特定於每個實例,因此無法實現。

但是,您可以使用__getattr__使一般想法工作。 這是一個實現,我認為你可以根據名稱到函數的字典映射做到這一點:

class MyClass(object):
    def __init__(self, func_dict):
        self.func_dict = func_dict

    def __getattr__(self, name):
        if name in self.func_dict:
            return self.func_dict[name]()     # call the function

        raise AttributeError("{} object has no attribute named {}"
                             .format(self.__class__.__name__, name)) # or raise an error

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM