Можно ли получить доступ к исходному коду скрипта Python, переданного в Python по стандарту в? - PullRequest
3 голосов
/ 30 июня 2010

Это случайный вопрос, который скорее из любопытства, чем из какой-либо конкретной необходимости.

Можно ли написать некоторый код на Python, который будет распечатывать некоторые вещи, включая сам исходный код, безхранить код Python в файле?Например, сделав что-то подобное в приглашении Bash:

$ echo '
> print "The Code:"
> PrintScript() # What would this function look like?
> for i in range(5):
>     print i,
> print "!"
> ' | python

и получите вывод, подобный следующему:

The Code:
print "The Code:"
PrintScript() # What would this function look like?
for i in range(5):
    print i,
print "!"
0 1 2 3 4 5 !

Я подозреваю, что это, вероятно, не может быть сделано, но с учетомСпособности Python к самоанализу, мне было любопытно узнать, распространяется ли он на этот уровень.

Ответы [ 4 ]

3 голосов
/ 30 июня 2010

Да, действительно возможно написать программу, которая выводит свой собственный источник. Для выполнения этих задач вам даже не нужен самоанализ, вам просто нужно уметь печатать вычисленные строки (работает с каждым языком).

Техника называется Quine , и вот довольно короткий пример на Python:

quine = 'quine = %r\r\nprint quine %% quine'
print quine % quine

Но квины не ограничиваются такими простыми программами. Они могут делать гораздо больше, например, печатать свой собственный источник задом наперед и так далее ...:)

2 голосов
/ 30 июня 2010

Это самое близкое, что я получаю:

echo 'import  __main__,inspect;print inspect.getsource(__main__)' | python

, что не получается ... В любом случае, исходный код съедается (читается из stdin) интерпретатором при запуске.Самое большее, вы можете получить доступ к скомпилированному коду через модуль __main__.

Обновление:

Модуль dis должен дать вам разборку всех функцийв модуле, но даже этот не видит никакого кода:

$ echo -e 'import  __main__,dis;print dis.dis(__main__)' | python
None

И даже когда я добавляю функцию:

$ echo -e "import  __main__,dis;print dis.dis(__main__)\ndef x():\n pass" | python
None
1 голос
/ 30 июня 2010

самое близкое, что вы можете получить, это использовать readline для запроса истории команд, если она доступна из того, что я вижу например, , но я подозреваю, что это может не содержать материал, переданный в сеанс, и в любом случае будет работать только для интерактивных сеансов

1 голос
/ 30 июня 2010

print open(__file__).read(),

Это будет работать на системах UNIX, я думаю, но я не уверен насчет Windows.Завершающая запятая гарантирует, что исходный код печатается точно, без дополнительной завершающей строки.

Только что понял (основываясь на комментариях ниже), что это не работает, если ваш исходный код взят из sys.stdin, что именно то, что вы просили.В этом случае вы можете воспользоваться некоторыми идеями, изложенными на этой странице о квинах (программах, печатающих собственные исходные коды) в Python, но ни одно из решений не будет единственной функцией, которая просто работает.Обсуждение, не зависящее от языка, здесь .

Короче говоря, нет, я не думаю, что это возможно с одной функцией, если ваш исходный код поступает из стандартного ввода. может иметь возможность получить доступ к интерпретированной форме вашей программы как к объекту кода Python и перевести ее обратно в исходную форму, но переведенная форма почти наверняка не будет точно соответствовать исходному содержимому файла.(Например, комментарии и строка Шебанга, безусловно, будут удалены).

...