Python:从项列表中定义构造函数中的属性

时间:2013-01-04 22:42:49

标签: python class properties

我想在我的类的构造函数中声明属性。

MaterialOne类显示了我当前的拥有方式。每个房产都必须单独定义。但是,我将拥有类似属性的组,我想给出相同的fset / fget / fdel。

由于需要大量代码来显式显示所有属性,因此我想以更简洁的方式定义属性。因此,我想让构造函数处理这个问题。 Class MateralTwo展示了我的想法。

不幸的是它不起作用,因为我得到了TypeErrors:

TypeError: get_property() takes exactly 1 argument (2 given)

我能理解为什么会抱怨,但我想不出任何解决方案。我不一定要在构造函数中的列表中定义属性。我正在寻找的是一种更简洁,更简洁的方法来定义它们。

class MaterialOne(object):
    def __init__(self):
        pass;

    def del_property(attr):
        """Abstract deller"""
        def del_attr(self):
            setattr(self, attr, None);
        return del_attr

    def set_property(attr):
        """Abstract setter."""
        def set_attr(self, x):
            setattr(self, attr, x);            
        return set_attr

    def get_property(attr):
        """Abstract getter"""
        def get_attr(self):
            if getattr(self, attr) is not None:
                return getattr(self, attr); 
            else:
                return 'Some calculated value..'
        return get_attr

    _young = None;
    _shear = None;
    _poisson = None;

    young = property(fget=get_property('_young'), fset=set_property('_young'), fdel=del_property('_young'));
    shear = property(fget=get_property('_shear'), fset=set_property('_shear'), fdel=del_property('_shear'));
    poisson = property(fget=get_property('_poisson'), fset=set_property('_poisson'), fdel=del_property('_poisson'));


class MaterialTwo(object):
    def __init__(self):
        properties = ['young', 'shear', 'poisson'];
        self.create_properties(properties)

    def del_property(attr):
        """Abstract deller"""
        def del_attr(self):
            setattr(self, attr, None);
        return del_attr

    def set_property(attr):
        """Abstract setter."""
        def set_attr(self, x):
            setattr(self, attr, x);            
        return set_attr

    def get_property(attr):
        """Abstract getter"""
        def get_attr(self):
            if getattr(self, attr) is not None:
                return getattr(self, attr); 
            else:
                return 'Some calculated value..'
        return get_attr        

    def create_properties(self, items):
        for item in items:
            storage = '_'+item;
            setattr(self, storage, None);
            setattr(self, item, property(fget=self.get_property(storage), fset=self.set_property(storage), fdel=self.del_property(storage)));


steel = MaterialOne(); 
steel.young = 2e11;
steel.poisson = 0.3;
print steel.poisson
print steel.shear

carbon = MaterialTwo();
carbon.young = 2e11;
carbon.poisson = 0.3;
print carbon.poisson
print carbon.shear

详细说明代码。我想写的是材料类,固体,液体,气体,它们都是材料的子类。将分配许多材料属性。可以基于已经定义的一些来计算一些。给定两个弹性模量,例如可以计算三分之一。

我现在使用与MaterialOne非常相似的东西实现了。然而,随着我获得更多的材料属性,并且还将包括更多这类计算,我想使它更清洁,更有条理。像我在MaterialTwo中那样写它对我来说是可能的。

3 个答案:

答案 0 :(得分:1)

setattr(self, item, property(...

这最终是你的问题。由于属性是描述符,因此它们必须绑定到类,而不是实例。您需要override __getattr__(), __setattr__(), and __delattr__()并在那里实施。

答案 1 :(得分:0)

所有定义都应以self作为第一个参数。

以下是这些功能的用法:

def del_property(self, attr):
def sel_property(self, attr):
def get_property(self, attr):

答案 2 :(得分:-1)

当在Python中的对象上调用方法时,该对象将作为第一个参数静默传递,这就是为什么你会收到一个错误,说你传递了太多的参数。正如其他人所说,你需要将self作为函数的第一个参数。