我正在处理导入后用作变量的数据。然后,我想使用对象中的变量作为属性。
到目前为止,我已经通过编写一个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))
我不喜欢这种组合解决方案,因为每次需要访问属性时,我都必须输入额外的"data“,但我也不确定继承是不是正确的方法。
我是不是在左外野,有更好的解决方案?
发布于 2017-01-13 07:22:46
您认为组合解决方案中的链式属性访问是一种代码气味的感觉是正确的:data
是Obj
的实现细节,应该对Obj
的客户端隐藏,因此如果ImportData
类的实现发生更改,您只需更改Obj
,而不是每个调用obj.data
的类。
我们可以通过给Obj
一个__getattr__
方法来隐藏Obj.data
,以控制如何访问它的属性。
>>> 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__
,而不是引发异常。
在上面的代码中,如果data
上不存在该属性,则Obj.__getattr__
将在Obj
上查找该属性,因此Obj
的客户端可以调用obj.slope
而不是obj.data.slope
。
https://stackoverflow.com/questions/41621117
复制相似问题