tomysshadow tomysshadow - 12 days ago 10
Python Question

Python Class "Main" Value

I'm pretty new to Python and have been writing a code that will read and write from a binary file.

I decided to create classes for every type of data that will be contained within the file, and to keep them organized I made one class they would all inherit, called InteriorIO. I want each class to have a read and write method which would read/write the data to/from the file. At the same time as inheriting InteriorIO however, I want them to behave like str or int in that they return the value they contain, so I'd modify either

__str__
or
__int__
depending on what they most closely resemble.

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()


The code on the bottom works, but the classes feel wrong and too ambiguous. I'm setting
this.value
, which is a random name I came up with, for every object as a sort of "main" value, and then returning said value as the type I want it to be.

What is the cleanest way to organize my classes such that they all inherit from InteriorIO, yet behave like a str or int in that they return their value?

Answer

I think in that case you may want to consider the Factory Design Pattern.

Here is a simple example to explain the idea:

class Cup:
    color = ""

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

class RedCup(Cup):
    color = "red"

class BlueCup(Cup):
    color = "blue"

# A little testing
redCup = Cup.getCup("red")
print "%s(%s)" % (redCup.color, redCup.__class__.__name__)

blueCup = Cup.getCup("blue")
print "%s(%s)" % (blueCup.color, blueCup.__class__.__name__)

So you have a factory Cup which contains a static method getCup which given a value, will decide which object to "generate" hence the title "factory".

Then in your code you only need to call the factory's getCup method and this will return you back with the appropriate class to work with.

They way to deal with __int__ and __str__ I think in the classes where you are missing either, just implement it and return back None. So your U16IO should implement a __str__ method that return None and your byteIO should implement a __int__ that also return None.