Объявление переменных и вопроса об объеме для Lua

Вот список дополнительных подходов:

Дан

import itertools as it
import collections as ct

import more_itertools as mit


iterable = range(11)
n = 3

Код

Стандартная библиотека

list(it.zip_longest(*[iter(iterable)] * n))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

d = {}
for i, x in enumerate(iterable):
    d.setdefault(i//n, []).append(x)

list(d.values())
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

dd = ct.defaultdict(list)
for i, x in enumerate(iterable):
    dd[i//n].append(x)

list(dd.values())
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

more_itertools + sup>

list(mit.chunked(iterable, n))
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

list(mit.sliced(iterable, n))
# [range(0, 3), range(3, 6), range(6, 9), range(9, 11)]

list(mit.grouper(n, iterable))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

list(mit.windowed(iterable, len(iterable)//n, step=n))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

Список литературы

+ sup> Сторонняя библиотека, в которой реализованы рецепты itertools и другие. > pip install more_itertools

5
задан Watusimoto 24 June 2009 в 22:05
поделиться

4 ответа

Нет возможности установить это поведение, но есть модуль "strict", поставляемый со стандартной установкой, который делает именно это (путем изменения мета-таблиц). Использование: require 'strict'

Для получения более подробной информации и других решений: http://lua-users.org/wiki/DetectingUndefinedVariables , но я рекомендую 'strict'.

3
ответ дан 14 December 2019 в 08:58
поделиться

«Локальное по умолчанию неверно ». См.

http://lua-users.org/wiki/LocalByDefault

http://lua-users.org/wiki/LuaScopingDiscussion

Вам необходимо использовать какую-то глобальную защиту окружающей среды. Для этого есть несколько статических инструментов (не слишком зрелых), но наиболее распространенным решением является использование защиты во время выполнения, основанной на __ index и __ newindex в _G метатаблица.

плагин Shameles: эта страница также может быть полезна:

http://code.google.com/p/lua-alchemy/wiki/LuaGlobalEnvironmentProtection

Обратите внимание, что пока обсуждается Lua, встроенный в swf, описанный метод (см. источники ) действительно работает для общего Lua. Мы используем что-то подобное в нашем производственном коде на работе.

2
ответ дан 14 December 2019 в 08:58
поделиться

На самом деле, дополнительной глобальной переменной с устаревшей ссылкой на корабль будет достаточно, чтобы GC не отбросил объект. Таким образом, его можно было обнаружить во время выполнения, заметив, что корабль теперь «мертв», и отказавшись что-либо с ним делать. Это все еще не тот корабль, но, по крайней мере, вы не разбились.

Вы можете сделать одно - хранить пользовательские сценарии в песочнице , возможно, в песочнице для каждого сценария. При правильном изменении таблицы окружения песочницы или ее метатаблицы вы можете организовать удаление всех или большинства глобальных переменных из песочницы до (или сразу после) вызова кода пользователя.

Очистка песочницы после вызовов будет иметь то преимущество, что отбрасывает лишние ссылки на вещи, которые не должны торчать. Это можно сделать, сохранив белый список полей, которым разрешено оставаться в среде, и удалив все остальные.

Например, следующий код реализует изолированный вызов пользовательской функции со средой, содержащей только имена из белого списка, за новой рабочей таблицей, предоставляемой для каждого вызова.

-- table of globals that will available to user scripts
local user_G = {
        print=_G.print,
        math=_G.math,
        -- ...
    }
-- metatable for user sandbox
local env_mt = { __index=user_G }


-- call the function in a sandbox with an environment in which new global 
-- variables can be created and modified but they will be discarded when the 
-- user code completes.
function doUserCode(user_code, ...)
    local env = setmetatable({}, env_mt) -- create a fresh user environment with RO globals
    setfenv(user_code, env)        -- hang it on the user code
    local results = {pcall(user_code, ...)}
    setfenv(user_code,{})
    return unpack(results)
end

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

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

0
ответ дан 14 December 2019 в 08:58
поделиться

Сорта.

В Lua глобальные объекты условно находятся в таблице глобальных объектов _G (на самом деле все немного сложнее, но со стороны Lua нет возможности скажите AFAIK). Как и в случае со всеми другими таблицами Lua, можно присоединить метатаблицу __ newindex к _G , которая контролирует, как к ней добавляются переменные. Позвольте этому обработчику __ newindex делать все, что вы хотите, когда кто-то создает глобал: выдает ошибку, разрешает, но выводит предупреждение и т. Д.

Чтобы вмешаться в _G , это Самый простой и понятный в использовании setfenv . См. Документацию .

2
ответ дан 14 December 2019 в 08:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: