Use name of a class as a parameter of a function in Python to make it work for several class types
Question:
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)
Answers:
Lets imagine you have a class A
class A:
pass
If you call str the result should be <class '__main__.A'>
:
str(A) == "<class '__main__.A'>"
for get class name you can use __name__
method
str_to_class(Reference.__name__)
or modify your function to str_or_class_to_class
😉
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")
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)
Lets imagine you have a class A
class A:
pass
If you call str the result should be <class '__main__.A'>
:
str(A) == "<class '__main__.A'>"
for get class name you can use __name__
method
str_to_class(Reference.__name__)
or modify your function to str_or_class_to_class
😉
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")