Как можно записать в одну строку скрипт на Python?
Есть код:
import socket
s = socket.socket()
s.connect(('192.168.0.195', 6969))
with open('hello.txt', "rb") as f:
buffer = f.read(4096)
while buffer:
s.sendall(buffer)
buffer = f.read(4096)
s.close()
Возможно ли его записать в одну строку (через ;), чтобы можно было исполнить через python -c '...'?
Ответы (3 шт):
Можно закодировать текст кода в base64, после через eval его выполнить.
Сделаю пример, а вы сами в code поместите ваш код
Пример:
import base64
code = '''\
for i in range(5):
print(i)
print('Finish!')
'''
code = base64.b64encode(code.encode('utf-8'))
print(code)
# b'Zm9yIGkgaW4gcmFuZ2UoNSk6CiAgICBwcmludChpKQpwcmludCgnRmluaXNoIScpCg=='
# Выполнять так:
# eval(compile(base64.b64decode(code), '<string>', 'exec'))
Теперь в консоли:
> python -c "import base64; code = b'Zm9yIGkgaW4gcmFuZ2UoNSk6CiAgICBwcmludChpKQpwcmludCgnRmluaXNoIScpCg==';
eval(compile(base64.b64decode(code), '<string>', 'exec'))"
0
1
2
3
4
Finish!
Да, можно. Вот короткий пример:
echo -e "import sys\nfor r in range(10): print 'rob'" | python
или
python -c "exec(\"import sys\nfor r in range(10): print 'rob'\")"
или
(echo "import sys" ; echo "for r in range(10): print 'rob'") | python
Обратите внимание в примере на цикл for (у Вас также вложенные with и while).
Как верно заметили выше, можно завернуть весь текст в одну строку с сохранением табуляций и подсунуть это функции exec(), заменив все переносы на \n, а каждый отступ на \t:
exec("""import socket\ns = socket.socket()\ns.connect(('192.168.0.195', 6969))\nwith open('hello.txt', "rb") as f:\n\tbuffer = f.read(4096)\n\twhile buffer:\n\t\ts.sendall(buffer)\n\t\tbuffer = f.read(4096)\ns.close()""")
Но также записывать выражения в одну строчку позволяет точка с запятой, но у такого подхода есть существенное ограничение на вложенные блоки, поэтому фрагменты с with и while придётся переписать.
Для данного случая можно переделать цикл до конца файла поблоковым циклом с вычислением размера файла:
import socket
import os
s = socket.socket()
s.connect(('192.168.0.195', 6969))
filename = 'hello.txt'
f = open(filename, "rb") # не используем with
sz = os.path.getsize(filename) # получаем размер файла в байтах
part = 4096
gen = (f.read(part) for i in range(sz // part + 1)) # генератор для получения новой порции
[s.sendall(buffer) for buffer in gen] # используем генератор для цикла
f.close()
s.close()
Или в одну строчку:
import socket;import os;s = socket.socket();s.connect(('192.168.0.195', 6969));filename = 'hello.txt';f = open(filename, "rb");sz = os.path.getsize(filename);part = 4096;gen = (f.read(part) for i in range(sz // part + 1));[s.sendall(buffer) for buffer in gen];f.close();s.close()
Одну строчку читать всё равно тяжело, но её может развернуть IDE стандартными средствами оформления