2017-01-12 6 views
0

私は変数をインポートした後に変数として使用するデータを扱っています。私はその後、属性としてオブジェクト内の変数を使用したいと思います。オブジェクト属性としてデータをインポートして使用するPythonic方法

これまで、私は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)) 

私は好きではない私は、以下の例を持っています私が属性にアクセスする必要があるたびに余分な "データ"をタイプする必要があるのでどちらかに行くのが正しい方法です。

私は左のフィールドに出ていますが、より良い解決策がありますか?

答えて

0

なる溶液中の連鎖属性アクセスは、コードのにおいであることをあなたの感覚が正しい:dataObjの実装の詳細であると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__を呼び出します。 Objのクライアントはobj.slope代わりのobj.data.slopeを呼び出すことができますので、それは、Obj上に存在しない場合は上記のコードで

Obj.__getattr__dataの属性を検索します。 AttributeErrorの再発生は、エラーメッセージが ImportData

+0

ではなく、Objを参照するように行われます。誰かが「o」と入力した場合を除いて、これはクールです。 IDEはデータをオプションとして一覧表示します。もう一つ興味深いのは、o.slopeへの代入はoに入っていますが、メソッドを中断しないことです。この場合、継承よりも構成はまだ良いですか? – StevenD

+0

IDEのコード補完のこの特定のケースでは、おそらくそうではありません。それが問題であれば、 'data'の先頭にアンダースコア(' _data')をつけて、コードの読者に、直接アクセスすべきではないObjの実装の詳細を示すことができます。しかし、これは継承が合成よりも、またはその逆であることを意味しません。解決しようとしている問題に応じて、どちらも長所と短所があります。 – snakecharmerb

関連する問題