Python矢量类

jed*_*mao 6 python class vector object maya

我来自C#背景,这个东西非常简单 - 试图将其翻译成Maya的Python.

必须有一个更好的方法来做到这一点.基本上,我正在寻找创建一个简单地具有x,y和z坐标的Vector类,但如果这个类返回一个包含所有3个坐标的元组并且如果你可以通过x编辑这个元组的值,那将是理想的,不知何故,y和z属性.

这是我到目前为止所做的,但是必须有比使用exec语句更好的方法,对吗?我讨厌使用exec语句.

class Vector(object):
    '''Creates a Maya vector/triple, having x, y and z coordinates as float values'''

    def __init__(self, x=0, y=0, z=0):
        self.x, self.y, self.z = x, y, z

    def attrsetter(attr):
        def set_float(self, value):
            setattr(self, attr, float(value))
        return set_float

    for xyz in 'xyz':
        exec("%s = property(fget=attrgetter('_%s'), fset=attrsetter('_%s'))" % (xyz, xyz, xyz))
Run Code Online (Sandbox Code Playgroud)

Chr*_*heD 5

如果我理解你的问题,你想要这样的东西吗?

class Vector(object):

    def __init__(self, x=0, y=0, z=0):
        self._x, self._y, self._z = x, y, z

    def setx(self, x): self._x = float(x)
    def sety(self, y): self._y = float(y)        
    def setz(self, z): self._z = float(z)     

    x = property(lambda self: float(self._x), setx)
    y = property(lambda self: float(self._y), sety)
    z = property(lambda self: float(self._z), setz)
Run Code Online (Sandbox Code Playgroud)

这使用_x,_y和_z来(内部)存储传入的值并通过使用属性(使用getter,setter)公开它们; 我使用lambda语句缩写'getters'.

请注意,在Python中,直接在对象本身上操作这些值(例如:x,y,z)是非常常见的(我想你想要确保显式的浮点转换?)


mar*_*eau 4

编辑:我已经用我的答案对 @unutbu 的原始答案进行了更多修改,以简化它并使正在做的事情更清晰。在最新版本中,@staticmethod已被完全消除并被嵌套单行代码取代。外部函数和嵌套类已被重命名AutoFloatProperties_AutoFloatProperties以反映它们转换和存储指定为浮点数的值的专门行为。尽管如此,@unutbu 自己使用类装饰器而不是元类修改后的答案是一个稍微简单的解决方案,尽管内部结构和用法非常相似。

def AutoFloatProperties(*props):
    '''metaclass'''
    class _AutoFloatProperties(type):
        # Inspired by autoprop (http://www.python.org/download/releases/2.2.3/descrintro/#metaclass_examples)
        def __init__(cls, name, bases, cdict):
            super(_AutoFloatProperties, cls).__init__(name, bases, cdict)
            for attr in props:
                def fget(self, _attr='_'+attr): return getattr(self, _attr)
                def fset(self, value, _attr='_'+attr): setattr(self, _attr, float(value))
                setattr(cls, attr, property(fget, fset))
    return _AutoFloatProperties

class Vector(object):
    '''Creates a Maya vector/triple, having x, y and z coordinates as float values'''
    __metaclass__ = AutoFloatProperties('x','y','z')
    def __init__(self, x=0, y=0, z=0):
        self.x, self.y, self.z = x, y, z # values converted to float via properties

if __name__=='__main__':
    v=Vector(1,2,3)
    print(v.x)
    # 1.0
    v.x=4
    print(v.x)
    # 4.0
Run Code Online (Sandbox Code Playgroud)