动态添加属性和设置器的 Pythonic 方式
Pythonic way to dynamically add properties and setters
我正在为 3D 应用程序开发一个库,它将应用程序的功能包装到一组 Python classes 中,并添加应用程序没有的附加功能.
我的基础 class 中有一组属性可以使用现有 API 向节点添加属性,但我想要一种更优雅的动态添加属性的方法。我目前有这段代码(如果不熟悉 3D 应用程序,这可能没有多大意义)但重要的是
# Add block properties
和
# PROPERTIES
代码。
class Block(pyunify.Transform):
def __init__(self, name = "Character"):
pyunify.Transform.__init__(self, name)
self.LockTransform()
class Spine(Block):
def __init__(self, name = "Character", numberOfJoints=6):
Block.__init__(self, name+"_spine")
# Add block properties
self.AddAttr("numberOfJoints", "long")
self.SetAttr("numberOfJoints", numberOfJoints)
# Create block template
self.Template()
# PROPERTIES
@property
def numberOfJoints(self):
return self.GetAttr("numberOfJoints")
@numberOfJoints.setter
def numberOfJoints(self, num):
self.SetAttr("numberOfJoints", num)
所以我可以预见额外的 classes 有更多的属性,以及我现在拥有它的方式,对于每个 属性 我必须将它添加到 _init__
self.AddAttr("numberOfJoints", "long")
self.SetAttr("numberOfJoints", numberOfJoints)
然后我必须在我的 class 中添加 2 个附加函数,一个 getter 和 setter,因为 属性 这样我就可以在我的内部调用它class 作为 self.numberOfJoints,它将与 class 本身交互,并在 3D 应用程序的伴随节点上设置正确的属性。
@property
def numberOfJoints(self):
return self.GetAttr("numberOfJoints")
@numberOfJoints.setter
def numberOfJoints(self, num):
self.SetAttr("numberOfJoints", num)
与其他 属性 函数的唯一区别是名称,所以我想知道是否有一种方法可以在我的基本块 class 中创建一个 AddProperty 函数,这样我就可以只需在我的 _init__ 函数中执行此操作:
self.AddProperty("numberOfJoints", "long")
self.numberOfJoints = 5
除了 运行 当前 _init__ 行
之外,它还会动态创建 getter 和 setter 函数
self.AddAttr("numberOfJoints", "long")
如有任何帮助,我们将不胜感激!
谢谢!
如果你想做一些看起来像 属性 的访问,但在执行功能下,你想要一个 descriptor。描述符是一个看起来像 属性 但拦截 get 和 set 调用并允许您 运行 任何您需要的代码的对象。这是一个 Whosebug 问题,其中包含一个使用描述符更改对象翻译的示例:
您可以使用相同的技巧以更易读、更少 cmd 的方式创建、获取和设置自定义属性。
更多代码 here.
我正在为 3D 应用程序开发一个库,它将应用程序的功能包装到一组 Python classes 中,并添加应用程序没有的附加功能.
我的基础 class 中有一组属性可以使用现有 API 向节点添加属性,但我想要一种更优雅的动态添加属性的方法。我目前有这段代码(如果不熟悉 3D 应用程序,这可能没有多大意义)但重要的是
# Add block properties
和
# PROPERTIES
代码。
class Block(pyunify.Transform):
def __init__(self, name = "Character"):
pyunify.Transform.__init__(self, name)
self.LockTransform()
class Spine(Block):
def __init__(self, name = "Character", numberOfJoints=6):
Block.__init__(self, name+"_spine")
# Add block properties
self.AddAttr("numberOfJoints", "long")
self.SetAttr("numberOfJoints", numberOfJoints)
# Create block template
self.Template()
# PROPERTIES
@property
def numberOfJoints(self):
return self.GetAttr("numberOfJoints")
@numberOfJoints.setter
def numberOfJoints(self, num):
self.SetAttr("numberOfJoints", num)
所以我可以预见额外的 classes 有更多的属性,以及我现在拥有它的方式,对于每个 属性 我必须将它添加到 _init__
self.AddAttr("numberOfJoints", "long")
self.SetAttr("numberOfJoints", numberOfJoints)
然后我必须在我的 class 中添加 2 个附加函数,一个 getter 和 setter,因为 属性 这样我就可以在我的内部调用它class 作为 self.numberOfJoints,它将与 class 本身交互,并在 3D 应用程序的伴随节点上设置正确的属性。
@property
def numberOfJoints(self):
return self.GetAttr("numberOfJoints")
@numberOfJoints.setter
def numberOfJoints(self, num):
self.SetAttr("numberOfJoints", num)
与其他 属性 函数的唯一区别是名称,所以我想知道是否有一种方法可以在我的基本块 class 中创建一个 AddProperty 函数,这样我就可以只需在我的 _init__ 函数中执行此操作:
self.AddProperty("numberOfJoints", "long")
self.numberOfJoints = 5
除了 运行 当前 _init__ 行
之外,它还会动态创建 getter 和 setter 函数self.AddAttr("numberOfJoints", "long")
如有任何帮助,我们将不胜感激!
谢谢!
如果你想做一些看起来像 属性 的访问,但在执行功能下,你想要一个 descriptor。描述符是一个看起来像 属性 但拦截 get 和 set 调用并允许您 运行 任何您需要的代码的对象。这是一个 Whosebug 问题,其中包含一个使用描述符更改对象翻译的示例:
您可以使用相同的技巧以更易读、更少 cmd 的方式创建、获取和设置自定义属性。
更多代码 here.