Я пишу функцию, которая получает filename, считывает информацию из файла и создает из него объект Read.
def read_file(filename):
with open(filename, 'r') as filetoread:
readList = []
for line in filetoread:
readList.append(Read(line))
return readList
Эта реализация работает.
Теперь я хочу обобщить свою функцию и заставить ее работать для двух типов объектов/классов: Read и Reference. Итак, я хочу использовать имя класса в качестве параметра функции. Теперь функция получает filename и classname. Он считывает информацию из файла и создает из него объект указанного classname.
Моя попытка выглядит так.
def read_file(filename, classname):
with open(filename, 'r') as filetoread:
readList = []
for line in filetoread:
readList.append(classname(line))
return readList
Я получаю TypeError: объект 'str' не может быть вызван.
Моя идея заключалась в использовании этого решения:
def str_to_class(classname):
return getattr(sys.modules[__name__], classname)
Источник: Преобразовать строку в объект класса Python?
Однако я все еще получаю сообщение об ошибке (TypeError: getattr(): имя атрибута должно быть строкой)
Было бы полезно знать, чего вы пытаетесь достичь. Как сказал @DeepSpace, я не понимаю, в чем цель этого, если у вас уже есть Reference
Дело в том, что мне нужно реализовать функцию, которая бы создавала объекты из файла. Таким образом, функция получает имя файла и имя класса, и в зависимости от пользовательского ввода могут быть созданы два разных типа класса. Вот так: def read(file, classname). Итак, если имя класса «Ссылка» - должен быть создан ссылочный объект, а если имя класса «Чтение» - должен быть создан объект чтения.
Это явно xy проблема. Вы должны спросить о вашей реальной проблеме.
@DeepSpace, ты прав. я изменил свой вопрос
@Hutch Я попытался объяснить, чего я пытаюсь достичь в своем обновлении вопроса. Извините за неясность.
@DeepSpace Теперь мой вопрос/проблема понятна?
@Kate_teryna Откуда этот файл? Вы сохраняете состояние своих объектов в файл? Похоже, вы пытаетесь выполнить сериализацию/десериализацию. Это звучит точно?
Я добавил ответ, но без более широкого контекста трудно сказать, как правильно с этим справиться. Я бы рассмотрел сериализацию/десериализацию.
Давайте представим, что у вас есть класс A
class A:
pass
Если вы вызываете str, результат должен быть <class '__main__.A'>:
str(A) == "<class '__main__.A'>"
Для получения имени класса вы можете использовать метод __name__
str_to_class(Reference.__name__)
Или измените свою функцию на str_or_class_to_class ;-)
Это не то, что пытается сделать OP. В любом случае, как вы представляете себе полезное использование str_to_class(Reference.__name__)? У вас уже есть Reference, зачем вам идти str_to_class(Reference.__name__) -> str_to_class("Reference") только для того, чтобы вернуть Reference?
Я не знаю, что пытается сделать ОП. Вы предлагаете вернуть класс из функции str_to_class, если она принимает классы. Я думаю, что это хорошая идея переименовать и изменить эту функцию на str_or_class_to_class (мое второе предложение).
Но в любом случае, может для этого вопроса достаточно использовать Reference.__name__, кто знает?
Что по-прежнему имело бы 0 смысла вообще. В любом случае это не должно быть ответом.
Ошибка: TypeError: 'str' object is not callable. говорит вам о вашей проблеме.
Чтобы объект был «вызываемым», он должен реализовать магический метод __callable__(). Строки не реализуют этот метод, и поэтому вы получаете эту ошибку.
Но ждать! Вы знаете, что реализует __callable__()? Классы!
Теперь вместо того, чтобы пытаться сделать какое-то преобразование, просто передайте необработанные символы. Это имя класса является token и будет рассматриваться как таковое.
Поэтому при вызове вашей функции
Использование: read_file("myFile.txt", Read)
И НЕ: read_file("myFile.txt", "Read")
Нет? Если у вас уже есть Reference, то зачем вам вообще эта функция?