Pull to refresh

Comments 24

Google Translate. Не, ну arbitary не переведенный — ладно, но стак? Знаю, что принято писать в личку, но это уже чересчур.

arbitary — где это вы нашли? И чем стак не угодил? Вполне себе ходит в таком варианте везде, как и стэк.
Соглашусь с Ivanq, слово стак имеет совершенно другое значение в английском и сбивает с толку, в то время как стэк уже давно используется в русском.

Если уж и перенимать английские слова, то перенимать правильное их значение.
Хм. Честно, но слышу про такое первый раз и про разницу между стаком и стэком. Если не очень сложно — можете провести короткий ликбез? А я тогда пока поправлю в переводе…
Большинство программистов говорят на английском, и когда при чтении видят знакомые английские термины, написанные как слова, имеющие совершенно другой смысл, это просто сбивает столку. И чем больше слов в предложении имеют неверные определения, тем сложнее читать текст

Это еще хорошо, когда ты знаешь определение обоих слов. А что делать новичкам, когда они впервые видят какое-то незнакомое слово в статье, и переведя его получают stuck => застрял

Хм. Ну насчёт большинство — это немного перебор, не в обиду, но просто со стороны именно курсов образования заметна выборка.

А стак-стэк — просто ещё в 90-е годы, да и в начале нулевых именно в написании на русском разницы не было. Видимо как-то внезапно оно устаканилось и прошло мимо. Спасибо за разъяснения, в статье всё поправил на привычное.
Соглашусь, большинство не знают английский в совершенстве, но, все же, все переменные и ключевые слова на английском, тут хочешь-не хочешь нужно знать хотя бы определение ключевых слов и терминов.

Вы же смотрите Rick and Morty (судя по кдпв), должны понимать, что новичкам часто сложно понять даже очевидные вещи :)

Так-то статья отличная, спасибо за перевод
Ну вот тут тоже есть нюансы. Я потихоньку собираю перлы от студентов, которые слышал и видел на наших курсах. Как силы будут — сделаю небольшую юмористическую подборку о разночтениях :)

Это да, но и так же есть вывод, что старые привычки искореняются тяжело :)

Не за что. Заходите ещё :) И вам ещё раз спасибо за поправки :)

Никогда не видел написания "стак". Либо стэк, либо стек (чаще).

Как минимум лет 5-6 назад видел тексты про «стакование». Не только в околоITшной среде причём.

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

Опечатлся. Не arbitary, а arbitrary.


# добавить функцию в стэк для выполнения arbitrary python

Чёрт, я там хотел залинковать ролик на ютубе и забыл :) Поправил, спасибо :)
Python 3.5.2 — прострел ноги из pickle — работает, а вот 2.7.12 как-то не хочет себе конечности отстреливать:
$ python
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pickled_bomb = b'c__builtin__\neval\n(Vprint "Bang! From, Evan."\ntR.'
>>> pickle.loads(pickled_bomb)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/pickle.py", line 1388, in loads
    return Unpickler(file).load()
  File "/usr/lib/python2.7/pickle.py", line 864, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 1139, in load_reduce
    value = func(*args)
  File "<string>", line 1
    print "Bang! From, Evan."
        ^
SyntaxError: invalid syntax
>>>

… что я делаю не так?

в 2 версии питона надо писать print("Bang! From, Evan.") — со скобками

Пробовал со скобками и без:
$ python
Python 2.7.12 (default, Dec  4 2017, 14:50:18) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pickled_bomb = b'c__builtin__\neval\n(Vprint("Bang! From, Evan.")\ntR.'
>>> pickle.loads(pickled_bomb)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/pickle.py", line 1388, in loads
    return Unpickler(file).load()
  File "/usr/lib/python2.7/pickle.py", line 864, in load
    dispatch[key](self)
  File "/usr/lib/python2.7/pickle.py", line 1139, in load_reduce
    value = func(*args)
  File "<string>", line 1
    print("Bang! From, Evan.")
        ^
SyntaxError: invalid syntax
… и это в третьем питоне прит — функция, во втором это оператор, с неформатированными параметрами воспринимает их как tupe

python 2:
>>> print(1,2)
(1, 2)

python 3:
>>> print(1,2)
1 2

Вообще-то ровно наоборот: во 2-м Python'е printинструкция, поэтому её можно писать без скобок, если напишем скобки, будет печататься кортёж. А вот в 3-м Python'е print уже сделали функцией, так что её вызов без скобок не канает.

Проблема в том, что eval() вычисляет только выражения, а во 2-м Python'е print — инструкция. Не помогает даже использование импорта из будущего


from __future__ import print_function

поскольку он, судя по всему, не влияет на контекст внутри функции eval(), восстановленной из pickle, так что превратить print в функцию не получается. Выполнять инструкции могла бы exec, но во втором Python'е это тоже инструкция (в отличие от третьего, где она стала функцией), поэтому в pickle её не подсунешь.


Python 2.7.13 (default, Jan 17 2017, 13:56:44)  [GCC 6.3.0 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> eval('''print(1)''')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    print(1)
        ^
SyntaxError: invalid syntax
>>> # Пробуем импорт функци print из будущего
>>> from __future__ import print_function
>>> eval('''print(1)''')
1
>>>
>>> # Но для pickle это всё равно не работает
>>> import pickle
>>> pickled_bomb = b'c__builtin__\neval\n(Vprint "Bang! From, Evan."\ntR.'
>>> pickle.loads(pickled_bomb)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:/Tools/msys64/mingw64/lib/python2.7/pickle.py", line 1388, in loads
    return Unpickler(file).load()
  File "D:/Tools/msys64/mingw64/lib/python2.7/pickle.py", line 864, in load
    dispatch[key](self)
  File "D:/Tools/msys64/mingw64/lib/python2.7/pickle.py", line 1139, in load_reduce
    value = func(*args)
  File "<string>", line 1
    print "Bang! From, Evan."
        ^
SyntaxError: invalid syntax
>>>

Удалось повторить трюк во 2-м Python'е. Рецепт успеха — функция compile():


Python 2.7.13 (default, Jan 17 2017, 13:56:44)  [GCC 6.3.0 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> # Проверяем, что print -- инструкция, если бы вывелось
>>> # <built-in function print>, она была бы функцией
>>> print
>>> 
>>> # Работает со скобками...
>>> pickled_bomb = b'''c__builtin__\neval\n(c__builtin__\ncompile\n(Vprint("Bang! From, Evan.", 1)\nV-\nVexec\ntRtR.'''
>>> pickle.loads(pickled_bomb)
('Bang! From, Evan.', 1)
>>> # ...и без них
>>> pickled_bomb = b'''c__builtin__\neval\n(c__builtin__\ncompile\n(Vprint "Bang! From, Evan., 1"\nV-\nVexec\ntRtR.'''
>>> pickle.loads(pickled_bomb)
Bang! From, Evan. 1
>>>

В первом случае выводится кортёж, во втором — подряд два аргумента инструкции. Со скобками трюк работает в обеих версиях Python'а. Суть: строим выражение


eval(compile('print("Bang! From, Evan.", 1)', '-', 'exec'))

и выполняем его. Второй аргумент функции compile() есть имя файла, третий указывает, что мы выполняем инструкции. Если бы мы указали там 'eval', ничего бы не заработало.

Чтобы ещё и результаты в обоих Python'ах были одинаковыми, передаём необязательные параметры в compile():


Python 2.7.13 (default, Jan 17 2017, 13:56:44)  [GCC 6.3.0 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> # 65536 == __future__.print_function.CompilerFlag
>>> # 0 -- не использовать инструкции из будущего из окружающего кода
>>> # (то есть, использовать только те, что указали предыдущим аргументом)
pickled_bomb = b'''c__builtin__\neval\n(c__builtin__\ncompile\n(Vprint("Bang! From, Evan.", 1)\nV-\nVexec\nI65536\nI0\ntRtR.'''
>>> pickle.loads(pickled_bomb)
Bang! From, Evan. 1
>>>

консервационный байт-код для метода десериализации объекта

Что это значит? Консервационный, по логике - прошедший сереализацию. Значит это байт код. Но тогда "консервационный байт код" звучит слишком перегружен терминами

Sign up to leave a comment.