Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:从项目列表在构造函数中定义属性_Python_Class_Properties - Fatal编程技术网

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

Python:从项目列表在构造函数中定义属性,python,class,properties,Python,Class,Properties,我想在类的构造函数中声明属性 这门课展示了我目前的情况。每个属性都必须单独定义。但是,我将有一些类似属性的组,我想给出相同的fset/fget/fdel 因为它需要大量代码来显式地编写所有属性,所以我希望以更简洁的方式定义属性。因此,我考虑让构造函数来处理这个问题。课堂材料2显示了我是如何想到这一点的 不幸的是,它不起作用,因为我遇到了类型错误: TypeError: get_property() takes exactly 1 argument (2 given) 我能理解它为什么抱怨,但我

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

这门课展示了我目前的情况。每个属性都必须单独定义。但是,我将有一些类似属性的组,我想给出相同的fset/fget/fdel

因为它需要大量代码来显式地编写所有属性,所以我希望以更简洁的方式定义属性。因此,我考虑让构造函数来处理这个问题。课堂材料2显示了我是如何想到这一点的

不幸的是,它不起作用,因为我遇到了类型错误:

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
我想进一步澄清一下代码。我想写的是材料的类,固体,液体,气体,每一个都是材料的一个子类。将只指定许多材质属性。一些可以根据已定义的参数进行计算。例如,给定两个弹性模量,可以计算出三分之一


我现在已经实现了这一点,只使用了与Material非常类似的东西。然而,随着我获得更多的材料属性,也将包括更多此类计算,我希望使其更干净、更有组织。我可以像在MaterialTwo中那样编写它。

所有定义的第一个参数都应该是
self

这些功能应该是这样的:

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

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


这最终是你的问题。由于属性是描述符,因此它们必须绑定到类,而不是实例。您将需要在那里创建和实现它。

风格点与您的问题无关:python中不需要分号,您最终要实现什么?(看起来您可能走错了方向。)您是否试图在首次访问属性时“按需”计算每个值,然后缓存该值?确切地说,就是这一行。正如您所说,描述符绑定到类而不是实例。因此,它无法从构造函数中工作。我现在明白了。我将看到覆盖将涉及到什么,但很可能我将不得不回到我独自一人所做的事情。
setattr(self, item, property(...