Как получить исходный код для класса Python, который я объявил программно? - PullRequest
1 голос
/ 20 января 2020

Я пытаюсь использовать inspect.getsource(), чтобы получить источник класса, который был определен следующим образом:

import inspect

Cat = type('Cat', (), {})

def meow_local(self):
  print("meow")

Cat.meow = meow_local

print(inspect.getsource(Cat))

Ошибка, которую я получаю при проверке:

OSError: не удалось найти определение класса

Понятно, что inspect не знает правильное место для поиска класса Cat. Где я должен сказать, чтобы проверить?

Или есть другой способ получить те же результаты?

1 Ответ

0 голосов
/ 21 января 2020

Ты не. И вы не можете, так как для него нет исходного кода.

inspect.getsource работает, обнаруживая файл actall .py, в котором что-то определено, и получая строки файла, как они находятся на диске , с комментариями, пробелами и тому подобным.

Даже если вы заполняете всю мета-информацию, необходимую для программно определенного класса, до уровня, вы получите значение __file__ и строчную информацию в объектах кода, getsource будет пытаться прочитать этот файл и получить текст там.

Вы ничего не упоминаете о своей реальной проблеме - если вы хотите иметь Python код для созданных вами классов, вы можете инвертировать эту вещь и проанализировать сгенерированные классы в write правильный файл .py, который делает то же самое, что и вызов программы c, на первом месте.

С другой стороны, если вам нужен исходный код для строк, содержащих вызов type, то выполнимо - но вам нужно будет настроить создание класса так, чтобы информация о номере файла и строки была указана в объекте кода, использованном для создания класса. Вызов type не использует объект кода для запуска - но есть способы сделать это, хотя и сложные. Некоторое время назад я ответил на вопрос о том, можно ли сделать программно объявленный класс неотличимым от нормального, объявленного класса - и я глубоко вникну в него - этот ответ покажет все мета-атрибуты, которые используются в обычным способом, некоторые из которых вам нужно будет заполнить - или еще хуже - forge , чтобы создать программный класс c, вызов создания которого можно определить getsource:

Определить, был ли класс определен декларативно или функционально - возможно?

...