[英]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.