PerlDuck
PerlDuck

Reputation: 5730

Is it OK to assign a reference to a module to a variable and then use the variable instead of the module?

Assume I have opened a file to read JSON data from it:

import json
with open('filename', 'r') as infile:
    data = json.load(infile)

For a pickle file I'd use:

import pickle
with open('filename', 'r') as infile:
    data = pickle.load(infile)

Now I want to be able to use my snippet for both formats, i.e.:

import json
import pickle

def read_data(filename, preferred_serializer)
    with open(filename, 'r') as infile:
        data = preferred_serializer.load(infile)
    return data

and call it like this:

data1 = read_data('file.pickle', pickle)
data2 = read_data('file.json', json)

This seems to work because both json and pickle share the same API load(infile). But I wonder whether it works just by accident or whether this is defined behaviour and a reasonable approach.

Upvotes: 1

Views: 41

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1123450

This is fine. Modules are just objects, just like everything else in Python.

It's not by accident that this works, it is by design, Python does try to be consistent in naming, so functions that deserialise data are generally called load. See marshal.load() for another example. Or yaml.load().

If you want to make it more generic still, you can store the load function references:

def read_data(filename, deserialize)
    with open(filename, 'r') as infile:
        data = deserialize(infile)
    return data

data1 = read_data('file.pickle', pickle.load)
data2 = read_data('file.json', json.load)

Functions are just objects too, after all, and now you made your function independent of the name of the callable.

Upvotes: 5

Related Questions