0

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

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

由于需要大量代码来显式编写所有属性,因此我想以更简洁的方式定义属性。因此,我想到让构造函数处理这个问题。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 中那样编写它对我来说是一种可能。

4

3 回答 3

1
setattr(self, item, property(...

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

于 2013-01-04T22:54:18.463 回答
0

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

这些功能应该是这样的:

def del_property(self, attr):
def sel_property(self, attr):
def get_property(self, attr):
于 2013-01-04T22:48:10.663 回答
-1

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

于 2013-01-04T22:52:03.660 回答