Информация об изменениях

Сообщение Re[3]: [python] eval не видит locals в list comprehension от 07.04.2023 5:43

Изменено 07.04.2023 5:45 Буравчик

Re[3]: [python] eval не видит locals в list comprehension
Здравствуйте, Кодт, Вы писали:

К>Хотя... я знаю, как пофиксить.

К>Напишу каскадный словарь.

Есть collestions.ChainMap, который как раз это и делает.
g = collestions.ChainMap(my_locals(), my_globals())


Хотя, для двух диктов он может работать медленнее.

К>ну или буду профилировать и смотреть, насколько страшен чёрт, если делать

К>g = copy.copy(dedicated_globals())

Я бы предпочел этот вариант. Копирование словаря очень быстрое, и отсутствуют накладные расходы при выполнении кода.

Возможно, лучше использовать unpacking — это чище, и даже быстрее (!).

g = {**my_globals(), **my_locals()}



Сделал небольшие замеры:

def copy_globals_unpack():
    return {**globals(), **{'a': 1, 'b': 2, 'c': 3}}

def copy_globals_naive():
    g = copy.copy(globals())
    l = {'a': 1, 'b': 2, 'c': 3}
    g.update(l)
    return g


In [9]: %timeit SuperGlobals(globals(), {'a': 1, 'b': 2, 'c': 3})
265 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [10]: %timeit copy_globals_unpack()
401 ns ± 2.05 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [11]: %timeit copy_globals_naive()
620 ns ± 1.09 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)


Время создания объекта SuperGlobals может быть сравнимо с временем копирования словаря (конечно, зависит от количества элементов).
Ну а при работе понятно, что скопированный словарь будет сильно быстрее.
Re[3]: [python] eval не видит locals в list comprehension
Здравствуйте, Кодт, Вы писали:

К>Хотя... я знаю, как пофиксить.

К>Напишу каскадный словарь.

Есть collestions.ChainMap, который как раз это и делает.
g = collestions.ChainMap(my_locals(), my_globals())


Хотя, для двух диктов он может работать медленнее.

К>ну или буду профилировать и смотреть, насколько страшен чёрт, если делать

К>g = copy.copy(dedicated_globals())

Я бы предпочел этот вариант. Копирование словаря очень быстрое, и отсутствуют накладные расходы при выполнении кода.

Возможно, лучше использовать unpacking — это чище, и даже быстрее (!?).

g = {**my_globals(), **my_locals()}



Сделал небольшие замеры:

def copy_globals_unpack():
    return {**globals(), **{'a': 1, 'b': 2, 'c': 3}}

def copy_globals_naive():
    g = copy.copy(globals())
    l = {'a': 1, 'b': 2, 'c': 3}
    g.update(l)
    return g


In [9]: %timeit SuperGlobals(globals(), {'a': 1, 'b': 2, 'c': 3})
265 ns ± 1.64 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [10]: %timeit copy_globals_unpack()
401 ns ± 2.05 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)

In [11]: %timeit copy_globals_naive()
620 ns ± 1.09 ns per loop (mean ± std. dev. of 7 runs, 1,000,000 loops each)


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