我正在处理导入后用作变量的数据。我想将对象中的变量用作属性。
到目前为止,我已经通过编写一个ImportData类来实现这一点,然后将它组成另一个类Obj,它将其用于其他计算。我使用的另一个解决方案是从ImportData类继承。我有一个例子如下:
class ImportData:
def __init__(self, path):
# open file and assign to some variables
# such as:
self.slope = 1
self.intercept = -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))
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;每次我需要访问一个属性,但我不确定继承是否正确。
我是否在左侧场地并且有更好的解决方案?
答案 0 :(得分:0)
您认为组合解决方案中的链式属性访问是代码味道是正确的:data
是Obj
的实现细节,应隐藏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