Pythonic方式导入和使用数据作为对象属性

时间:2017-01-12 19:13:38

标签: python class import attributes

我正在处理导入后用作变量的数据。我想将对象中的变量用作属性。

到目前为止,我已经通过编写一个ImportData类来实现这一点,然后将它组成另一个类Obj,它将其用于其他计算。我使用的另一个解决方案是从ImportData类继承。我有一个例子如下:

定义数据类

class ImportData:
    def __init__(self, path):
        # open file and assign to some variables
        # such as:
        self.slope = 1
        self.intercept = -1

解决方案1:使用组合

class Obj:
    def __init__(self, data_object):
        self.data = data_object

    def func(self, x):
        return self.data.slope*x + self.data.intercept


data_object = ImportData('<path>')
obj = Obj(data_object)

# get the slope and intercept
print('slope =', obj.data.slope, '  intercept =', obj.data.intercept)

# use the function
print('f(2) =', obj.func(2))

解决方案2:使用继承

class Obj(ImportData):
    def __init__(self,path):
        super().__init__(path)

    def func(self, x):
        return self.slope*x + self.intercept

obj = Object('<path>')
# get the slope and intercept
print('slope =', obj.slope, '  intercept =', obj.intercept)

# use the function
print('f(2) =', obj.func(2))

我不喜欢构图解决方案,因为我必须输入额外的&#34;数据&#34;每次我需要访问一个属性,但我不确定继承是否正确。

我是否在左侧场地并且有更好的解决方案?

1 个答案:

答案 0 :(得分:0)

您认为组合解决方案中的链式属性访问是代码味道是正确的:dataObj的实现细节,应隐藏Obj&#39;客户,所以如果ImportData类的实施发生变化,您只需更改Obj而不是每个调用obj.data的类。

我们可以通过Obj.data Obj方法隐藏__getattr__来控制其属性的访问方式。

>>> class ImportData:
...     def __init__(self, path):
...         self.slope = 1
...         self.intercept = -1
... 
>>> data = ImportData()


>>> class Obj:
...     def __init__(self, data_object):
...         self.data = data_object

...     def func(self, x):
...         return self.slope*x + self.intercept

...     def __getattr__(self, name):
...         try:
...             return getattr(self.data, name)
...         except AttributeError:
...             raise AttributeError('{} object has no attribute {}.'.format(self.__class__.__name__, name))

>>> o = Obj(data)
>>> o.func(2)
1
>>> o.slope
1
>>> o.intercept
-1
>>> 

通常,如果python无法找到对象的属性 - 例如obj.slope - 它将引发AttributeError。但是,如果对象具有__getattr__方法,则python将调用__getattr__而不是引发异常。

在上面的代码中,Obj.__getattr__会在data上查找属性,如果Obj上没有该属性,那么Obj的客户端可以拨打obj.slope而不是obj.data.slope。重新引发AttributeError,以便错误消息引用Obj而不是ImportData