2016-11-27 6 views
1

私はPythonには新しく、バイナリファイルから読み書きするコードを書いています。Pythonクラス "Main"値

私は、ファイルに格納されるすべてのタイプのデータのクラスを作成し、それらを整理しておくために、すべてが継承するクラスを作成しました。私は各クラスに、ファイルを読み書きするメソッドを持たせたいと思っています。しかし、InteriorIOを継承すると同時に、strやintのように振る舞い、値が返されるようにしたいので、最も近いものに応じて__str__または__int__のいずれかを変更します。

class InteriorIO(object): 
    __metaclass__ = ABCMeta 

    @abstractmethod 
    def read(this, f): 
     pass 

    @abstractmethod 
    def write(this, f): 
     pass 

class byteIO(InteriorIO): 
    def __init__(this, value=None): 
     this.value = value 

    def read(this, f): 
     this.value = struct.unpack("B", f.read(1))[0] 

    def __str__: 
     return value; 

class U16IO(InteriorIO): 
    def __init__(this, value=None): 
     this.value = value 

    def read(this, f): 
     this.value = struct.unpack("<H", f.read(2))[0] 

    def __int__: 
     return value; 

# how I'd like it to work 
f.open("C:/some/path/file.bin") 
# In the file, the fileVersion is a U16 
fileVersion = U16IO() 
# We read the value from the file, storing it in fileVersion 
fileVersion.read(f) 
# writes the fileVersion that was just read from the file 
print(str(fileVersion)) 
# now let's say we want to write the number 35 to the file in the form of a U16, so we store the value 35 in valueToWrite 
valueToWrite = U16IO(35) 
# prints the value 35 
print(valueToWrite) 
# writes the number 35 to the file 
valueToWrite.write(f) 
f.close() 

下のコードは機能しますが、クラスは間違っていてあまりにも曖昧です。私はthis.valueを設定しています。これは、すべてのオブジェクトに対して、「主な」値の一種として、そして私が望むタイプとしてその値を返すランダムな名前です。

クラスがすべてInteriorIOから継承されるようにクラスを整理する最もクリーンな方法はありますが、値を返すという点でstrやintのように振る舞いますか?

答えて

1

このケースでは、Factory Design Patternと思うかもしれません。ここで

がアイデアを説明するために簡単な例です:

class Cup: 
    color = "" 

    # This is the factory method 
    @staticmethod 
    def getCup(cupColor, value): 
     if (cupColor == "red"): 
      return RedCup(value) 
     elif (cupColor == "blue"): 
      return BlueCup(value) 
     else: 
      return None 

class RedCup(Cup): 
    color = "Red" 

    def __init__(self, value): 
     self.value = value 


class BlueCup(Cup): 
    color = "Blue" 

    def __init__(self, value): 
     self.value = value 

# A little testing 
redCup = Cup.getCup("red", 10) 
print("{} ({})".format(redCup.color, redCup.__class__.__name__)) 

blueCup = Cup.getCup("blue", 20) 
print("{} ({})".format(blueCup.color, blueCup.__class__.__name__)) 

ですから、値指定のstaticメソッドgetCupが含まれている工場Cupを持っている、 "ので、タイトルを「生成」するためにどのオブジェクトを決定します工場"。

あなたのコードでは、工場のgetCupメソッドを呼び出すだけで済みます。これにより、適切なクラスを返すことができます。

対処方法__int____str__いずれかが欠けているクラスでは、実装して戻ってきません。したがって、あなたのU16IOは、Noneを返す__str__メソッドを実装する必要があります。そして、あなたのbyteIOは、を取得してNoneを返す__int__を実装する必要があります。

+0

私が既に知っていた値を書き込むためにU16IOで行ったような、RedCup/BlueCupにどのように値を渡すことができますか? – tomysshadow

+1

@tomysshadow 'RedCup'と' BlueCup'は引き続きパラメータを受け入れることができるコンストラクタ(つまり '__init__')を持つことができます。ファクトリメソッドに渡された値によって、クラスを作成することを決定できますか?上記の例(私が追加したリファレンスから取ったもの)は最小ですが、コンストラクタとパラメータを渡すことができないというわけではありません。 – Rafael

+0

コンストラクタのケースを含めるように答えを更新しました。それに渡される。 – Rafael

1

なぜあなたはここでクラスを使用していますか?それは過度に複雑に思えます。

readwriteの2つの関数を定義できます。

def bread(format, binaryfile): 
    return struct.unpack(format, binaryfile.read(format.calcsize())) 

def bwrite(format, binaryfile, *args): 
    binaryfile.write(struct.pack(format, *args)) 
+0

私はまた、1つではなく2つまたは3つの値をとるより複雑なクラスを持っているからです。 – tomysshadow

+0

@tomysshadow 'bread'関数は、そのユースケースをすでに処理しているはずです。私は 'bwrite'もそれを扱うように変更しました。 –