Используйте имя класса в качестве параметра функции в Python, чтобы он работал для нескольких типов классов.

Я пишу функцию, которая получает 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(): имя атрибута должно быть строкой)

Нет? Если у вас уже есть Reference, то зачем вам вообще эта функция?

DeepSpace 10.01.2023 19:58

Было бы полезно знать, чего вы пытаетесь достичь. Как сказал @DeepSpace, я не понимаю, в чем цель этого, если у вас уже есть Reference

Hutch 10.01.2023 20:01

Дело в том, что мне нужно реализовать функцию, которая бы создавала объекты из файла. Таким образом, функция получает имя файла и имя класса, и в зависимости от пользовательского ввода могут быть созданы два разных типа класса. Вот так: def read(file, classname). Итак, если имя класса «Ссылка» - должен быть создан ссылочный объект, а если имя класса «Чтение» - должен быть создан объект чтения.

Hash_Mag 10.01.2023 20:08

Это явно xy проблема. Вы должны спросить о вашей реальной проблеме.

DeepSpace 10.01.2023 20:15

@DeepSpace, ты прав. я изменил свой вопрос

Hash_Mag 10.01.2023 20:40

@Hutch Я попытался объяснить, чего я пытаюсь достичь в своем обновлении вопроса. Извините за неясность.

Hash_Mag 10.01.2023 20:48

@DeepSpace Теперь мой вопрос/проблема понятна?

Hash_Mag 10.01.2023 21:13

@Kate_teryna Откуда этот файл? Вы сохраняете состояние своих объектов в файл? Похоже, вы пытаетесь выполнить сериализацию/десериализацию. Это звучит точно?

Hutch 10.01.2023 21:35

Я добавил ответ, но без более широкого контекста трудно сказать, как правильно с этим справиться. Я бы рассмотрел сериализацию/десериализацию.

Hutch 10.01.2023 21:58
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
Тонкая настройка GPT-3 с помощью Anaconda
Тонкая настройка GPT-3 с помощью Anaconda
Зарегистрируйте аккаунт Open ai, а затем получите ключ API ниже.
0
9
61
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Давайте представим, что у вас есть класс 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?

DeepSpace 10.01.2023 20:14

Я не знаю, что пытается сделать ОП. Вы предлагаете вернуть класс из функции str_to_class, если она принимает классы. Я думаю, что это хорошая идея переименовать и изменить эту функцию на str_or_class_to_class (мое второе предложение).

Kapustin Alexander 10.01.2023 20:22

Но в любом случае, может для этого вопроса достаточно использовать Reference.__name__, кто знает?

Kapustin Alexander 10.01.2023 20:23

Что по-прежнему имело бы 0 смысла вообще. В любом случае это не должно быть ответом.

DeepSpace 10.01.2023 20:23
Ответ принят как подходящий

Ошибка: TypeError: 'str' object is not callable. говорит вам о вашей проблеме.

Чтобы объект был «вызываемым», он должен реализовать магический метод __callable__(). Строки не реализуют этот метод, и поэтому вы получаете эту ошибку.

Но ждать! Вы знаете, что реализует __callable__()? Классы!

Теперь вместо того, чтобы пытаться сделать какое-то преобразование, просто передайте необработанные символы. Это имя класса является token и будет рассматриваться как таковое.

Поэтому при вызове вашей функции

Использование: read_file("myFile.txt", Read)

И НЕ: read_file("myFile.txt", "Read")

Другие вопросы по теме