10

I have a class which expects a stream that contains an XML file.
I don't necessarily want a file stream and I might want to use other sources like a database, a socket etc.
What class do I need to subclass from the io module in order to supply the stream interface from other sources?

the_drow
  • 18,571
  • 25
  • 126
  • 193
  • 1
    A socket already has the same interface as another file. A database connection usually provides a "blob" which can be turned into a file-line object using `StringIO`. Why are you subclassing something when your "stream" interface (i.e., Python's `file`) already exists? What's unique or different? – S.Lott Apr 05 '11 at 21:18
  • Why deriving? Python is not C++. Are you sure that just passing something that has a proper `read()` method isn't enough? – 6502 Apr 05 '11 at 21:34
  • @6502: The XML file can be loaded from a database into a stream. I'm just encapsulating behavior. – the_drow Apr 06 '11 at 07:04
  • @S.Lott: I want an object that already turns the blob into a file-like object. This kind of object should have the same interface as the file object in order for it to work with my class which expects a stream. – the_drow Apr 06 '11 at 07:07
  • @the_drow. That object is `StringIO.StringIO( blob )`. What more do you need? – S.Lott Apr 06 '11 at 10:04
  • @S.Lott: Who is responsible for creating that object? – the_drow Apr 06 '11 at 11:39
  • @the_drow: "responsible for creating that object"? It can't be the database -- you'd have to rewrite every RDBMS to include "blob-as-stream". It can't be any DB-API interface. You'd have to add "blob-as-stream" conversion to the DB-API standard and all implementations. Therefore, what's left? Only an application can decide that a blob should be used as a stream. If you have an alternative, please **update** the question with an example use case and explanation of what you'd like to see happen. – S.Lott Apr 06 '11 at 12:02
  • @S.Lott: What I had in mind is to inherit StringIO and encapsulate the loading behavior in it. For instance if I'm pulling the file from the database then in the derived class of StringIO's ctor/read method I'd perform the SQL query, load the results into a bulb and than pass it onwards to the StringIO ctor. – the_drow Apr 06 '11 at 12:05
  • @the_drow: "What I had in mind is..." Please **update** the question with the example use case and explanation of what you'd like to see happen. It's hard for us to synthesize your focused question from a lot of comments. Please **update** the question with pseudo-code showing your use case. – S.Lott Apr 06 '11 at 12:13
  • @S.Lott: Will be done once I get home from work – the_drow Apr 06 '11 at 12:39

2 Answers2

6

The answer given by Andrey isn't entirely correct.

In Python, streams are "file-like" objects. You can read/write to them using tools defined in the io module. The module also provides interfaces which you should implement if you want to define a stream object.

Note that the io module differentiates between three different types of streams, which require slightly different interfaces. (They differ mostly in terms of data types.)

  1. Text I/O - interface TextIOBase
  2. Binary I/O - interface BufferedIOBase
  3. Raw I/O - interface RawIOBase

StringIO for example is an in-memory implementation of the TextIOBase.

Note that these interfaces are available both on Python 2 and 3.

arnuschky
  • 2,159
  • 1
  • 19
  • 15
  • I needed to pass a file to openpyxl that was base64 serialized. I used `load_workbook(filename=io.BytesIO(base64.b64decode(base64_file)), read_only=True)` – UselesssCat Dec 24 '19 at 16:49
4

Dynamic typing allows you not to subclass from any base class in this case. You should implement some methods with proper names. Blog post on the subject

Andrey Sboev
  • 7,454
  • 1
  • 20
  • 37
  • 2
    What I don't get is why I shouldn't sub class. In any case my interface should be the stream's interface. – the_drow Apr 06 '11 at 07:57
  • I wrote only that you are able not to subclass using inheritance mechanism and may create your class and implement methods with needed signature is necessary and sufficient – Andrey Sboev Apr 06 '11 at 15:41