pythonparameter-passingclass-variables

Use name of a class as a parameter of a function in Python to make it work for several class types


I write a function that gets a filename, reads out information from the file and creates a Read object out of it.

def read_file(filename):   
  with open(filename, 'r') as filetoread:
        readList = []
        for line in filetoread:
            readList.append(Read(line))
        return readList

This implementation works.

Now I want to generalize my function and make it work for two object/class types: Read and Reference. So I want to use a class name as a parameter of a function. The function gets a filename and a classname now. It reads out information from the file and creates an object of a specified classname out of it.

My attempt lookes like this.

def read_file(filename, classname):
  with open(filename, 'r') as filetoread:
        readList = []
        for line in filetoread:
            readList.append(classname(line))
        return readList

I get TypeError: 'str' object is not callable.

My idea was using this solution:

def str_to_class(classname):
    return getattr(sys.modules[__name__], classname)

Source: Convert string to Python class object?

I still get an error though (TypeError: getattr(): attribute name must be string)


Solution

  • The error: TypeError: 'str' object is not callable. is telling you your problem.

    For an object to be "callable" it must implement the __callable__() magic method. Strings do not implement this method, and therefore you get this error.

    But wait! You know what does implement __callable__()? Classes!

    Now rather than trying to do some conversion, just pass in the raw characters. This classname is a token and will be treated as such.

    Therefore when calling your function

    Use: read_file("myFile.txt", Read)

    and NOT: read_file("myFile.txt", "Read")