Рубрики
Без рубрики

Как импортировать библиотеки в функции Python Exec ()?

https://www.youtube.com/watch?v=eknq_jgkoj8 Что такое функция exec () exec () – это встроенная функция Python, которая наиболее часто используется для динамически выполнения кода, либо в виде строки, либо объекта. Чтобы правильно понять, как мы можем использовать EXEC () для импорта библиотек и модулей, нам нужно ознакомиться с синтаксисом самой функции, поскольку оно становится актуальным … Как импортировать библиотеки в функции Python’s Exec ()? Прочитайте больше “

Автор оригинала: Rikesh Nichani.

Что такое функция EXEC ()

EXEC () это Встроенный Функция Python, которая наиболее часто используется для динамически выполнения кода, либо в виде строки, либо объекта. Правильно понять, как мы можем использовать EXEC () Для импорта библиотек и модулей нам нужно ознакомиться с синтаксисом самой функции, поскольку оно становится актуальным позже:

exec(object, globals, locals)

Как видите, он имеет три параметра, которые можно определить следующим образом:

  • объект : строка или объектный код для выполнения
  • глобал : a Словарь имеющихся глобальных методов и переменных (необязательно)
  • Местные жители : словарь имеющихся локальных методов и переменных (необязательно)

Основное использование

Теперь давайте посмотрим на то, как exec () можно использовать для динамически выполнения кода в его наиболее основной форме, либо в виде строки, либо на объекте:

program = 'a = 5; b=5; print("a x b  =", a*b)'
exec(program)
a x b = 25

По умолчанию EXEC () Поставляется с набором встроенных функций, которые могут быть выполнены без необходимости импорта, которые мы можем перечислить по Печать каталог следующим образом:

exec(print(dir()))
# ['In', 'Out', '_', '__', '___', '__builtin__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', '_dh', '_i', '_i1', '_ih', '_ii', '_iii', '_oh', 'exit', 'get_ipython', 'quit']

Так что, если мы хотим EXEC () сделать что-то за пределами этих библиотек по умолчанию? Можем ли мы импортировать библиотеки и динамически проходить их? Вы будете рады знать, что короткий ответ – да! Чтобы продемонстрировать, давайте возьмем пример datetime Модуль, который представляет собой стандартную библиотеку Python – настолько, в то время как ничего не нужно загружать, его необходимо импортировать для запуска.

Импортируйте модуль в строке кода

Самый простой способ импортирования библиотеки – включая оператор импорта в наш строковый или объектный код и передачу его через метод EXEC ():

program = '''
import datetime
print(datetime.datetime.now())
'''
exec(program)
# 2021-01-25 12:22:58.680938

Когда мы называем EXEC () Функция, она читает каждую строку кода и выполняет, поэтому основное оператор импорта работает в EXEC ( ) как обычно. С вышеуказанным кодом то, что мы в основном говорите:

exec(import datetime; print(datetime.datetime.now())

Мы можем подтвердить, что datetime Модуль на самом деле был импортирован путем проверки библиотек, которые теперь доступны в EXEC () Каталог:

exec(print(dir()))
# ['In', 'Out', …. 'datetime', 'exit', 'get_ipython', 'program', 'quit']

Как datetime Сейчас стал частью EXEC () Словарь его можно использовать EXEC () Функция по умолчанию где-нибудь еще в вашем коде, без необходимости еще раз импортировать.

Если мы тогда запустим:

prog = '''
print(datetime.datetime.now())
'''
exec(prog)
# 2021-01-25 12:23:53.207181

Код выполняет, даже если мы не просили явно спросили EXEC () импортировать модуль.

Теперь, что произойдет, если мы хотели импортировать datetime Модуль, а затем назовите его в другой объем, например функцию, может EXEC () Сделать это? Давайте посмотрим:

program = '''
import datetime
def f():
    print(datetime.datetime.now())
f()
'''
exec(program)
# 2021-01-25 12:26:49.306432

Итак, да, это также возможно, и мы можем подтвердить, что импорт работал, печать EXEC () каталог :

exec(print(dir()))
# ['In', 'Out', …. 'datetime', 'exit', 'get_ipython', 'program', 'quit']

Импортируйте модуль за пределами строки кода

В предыдущих примерах мы импортировали datetime как часть « Программа «Объектный код в строке. Исходя из нашего понимания того, как EXEC () Работает, выполняя строку кода по линии, казалось бы логичным, что EXEC () Функция импортирует модуль, так как он динамически работает через код.

Но что произойдет, если мы поместим оператор импорта за пределами нашего « Программа «Код? В следующем примере вы ожидаете, что код будет работать?

import datetime
program = '''
print(datetime.datetime.now())
'''
exec(program)

Если вы ответили «Да» – Поздравляем! Выход действительно:

# 2021-01-25 12:28:32.629759

Если, как я, когда я впервые увидел это, вы ответили «Нет», давайте посмотрим, что произошло и как это сработало. Мы можем четко видеть Импорт данных DateTime Команда за пределами строки кода ‘ Программа «И мы попросили его импортировать в рамках EXEC () функция.

Как мы видели в начале этого блога EXEC () Функция имеет 3 параметра; объект , Местные жители и глобал Отказ Так что, хотя импорт datetime Заявление не в нашем « Программа «Код его автоматически включен в EXEC () Функция через параметр глобал. Этот параметр, глобал () , Позволяет EXEC () Доступ к чему-либо во всей области программы, будь то наше намерение или нет. Мы можем подтвердить это, показывая EXEC () Словарь :

exec(print(dir()))
# ['In', 'Out', …. 'datetime', 'exit', 'get_ipython', 'program', 'quit']

Как и в предыдущем примере импорта в строке кода, потому что datetime Модуль теперь является частью EXEC () Справочник его можно вызвать снова, без необходимости специально импортировать его:

prog = '''
print(datetime.datetime.now())
'''
exec(prog)
# 2021-01-25 12:31:44.413763

Импорт и глобальный параметр

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

Как уже упоминалось, EXEC () имеет три параметра, объект , Местные жители и глобал И мы можем использовать их для управления, как мы импортируем библиотеки. Поскольку оба местных жителя, так и глобалы являются необязательными, если мы не указываем локальный параметр, параметр глобалей будет использоваться как глобальные, так и локальные.

Глобальный параметр и импорт внутри строки кода

Давайте сначала посмотрим на наш пример импорта внутри строки кода. Мы можем остановить библиотеку стать частью EXEC () каталог, поместив пустой словарь в глобалях {} параметр.

program='''
import datetime
print(datetime.datetime.now())
'''
exec(program, {})
2021-01-25 12:34:09.591599

На этот раз, в то время как наш код работал, как ожидалось, если мы распечатаем EXEC () каталог мы видим, что datetime был добавлен по умолчанию на встроенные:

exec(print(dir()))
# ['In', 'Out', , '_oh', 'exit', 'get_ipython', 'program', 'quit']

Так что если мы сейчас стараемся использовать datetime Модуль в другом EXEC () Позвоните, что мы получим следующее сообщение об ошибке:

prog = '''
print(datetime.datetime.now())
'''
exec(prog)
NameError: name 'datetime' is not defined

Глобальный параметр и импорт за пределами строки кода

Мы можем ограничить EXEC () от доступа к нашему глобальному импортным операторам, поместив пустой словарь {} В глобал параметр. Это остановит импортируемые внешние библиотеки снаружи или наши « Программа «Кодовая строка. В приведении ниже мы собираемся импортировать два модуля библиотечных библиотеки Python Standard, чтобы лучше проиллюстрировать нашу точку:

import datetime
import random
program = '''
print(datetime.datetime.now())
print(random.randint(0,9))
'''
exec(program, {})
# NameError: name 'datetime' is not defined.

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

exec(print(dir()))

Выход:

['In', 'Out…. '_oh', 'datetime', 'exit', 'get_ipython', 'program', 'quit', 'random']

В качестве альтернативы мы можем предупредить библиотеки, которые мы хотим разрешить доступ, указав их в рамках глобал Параметр, например:

import datetime
import random
program = '''
print(datetime.datetime.now())
print(random.randint(0,9))
'''
exec(program, {"datetime":datetime})
2021-01-25 12:39:49.800751
NameError: name 'random' is not defined

В приведенном выше коде только datetime Модуль включен в глобал Параметр, так можно получить доступ, в то время как Случайные остается ограниченным.

Локальный параметр и импорт за пределами строки кода

Так же, как глобал Параметр предлагает некоторое управление с импортом с использованием EXEC () Так что параметр Locals. С Местные жители () Мы можем указать, что может быть или не может быть включено. Например:

import datetime
program = '''
print(datetime.datetime.now())
'''
exec(program, {"__builtins__" : None}, {"datetime":datetime})
TypeError: 'NoneType' object is not subscriptable

Потому что мы заблокировали доступ к любому из EXEC () Встроенные с локальным параметром {"__builtins__": нет} они не могут быть доступен. Это несмотря на то, что мы указали, модуль можно получить доступ к глобальному параметру {"datetime": datetime} Отказ

И наоборот мы можем предоставить локальный доступ, даже если мы не хотим ограничить глобальный параметр:

import datetime
program = '''
print(datetime.datetime.now())
'''
exec(program,{"datetime":datetime}, {})

Предоставление глобального доступа к локальному параметру

Наконец, давайте посмотрим на то, что произойдет, если у нас есть модуль, доступный локально, что мы хотим включить в глобальный Параметр, например:

program = '''
import datetime
def f():
    print(datetime.datetime.now())
 
'''
def test():
exec(program)
f()
test()
# NameError

В этом примере мы получаем NameError потому что EXEC () находится в функции, поэтому datetime Модуль доступен только в этой функции «Тест» Отказ Мы проверяем модули, доступные в EXEC () Каталог::

exec(print(dir()))
['In', 'Out', , '_oh', 'exit', 'get_ipython', 'program', 'quit']

Как мы видим datetime Модуль не был уныренен в встроенные встроенные, так как он был импортирован только как Местный Переменная. Это означает, что библиотека доступна только в Тест Функция, и мы не можем использовать его вне этого. Мы можем проверить это, распечатав каталог local of Тест В рамках функции:

program= '''
import datetime
def f():
    print(datetime.datetime.now())
 
'''
def test():
exec(program)
exec(print(locals()))    
f()
test()
 
{'datetime': , 'f': }
TypeError

Так что теперь, а не ограничивая доступ, мы на самом деле хотим EXEC () импортировать datetime как глобальный параметр, а не локальный. Мы можем сделать это со следующим синтаксисом:

exec(program, globals())

Теперь, если мы снова запустим наш код с обновленным синтаксисом:

program= '''
import datetime
def f():
    print(datetime.datetime.now())
 
'''
def test():
exec(program, globals())
f()
test()
# 2021-01-25 12:55:11.031992

И просто чтобы подтвердить, что мы фактически импортировали библиотеку правильно, давайте распечатаем EXEC () Каталог:

exec(print(dir()))
['In', 'Out', …. 'datetime', 'exit', 'get_ipython', 'program', 'quit']

Резюме

Мы видели несколько вариантов для импорта библиотек в EXEC () функция. Ключевая вещь, которую нужно иметь в виду, что да, это можно сделать, но осторожность, однако рекомендуется!

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