Выполнить скрипт из строки с доступом к переменным? - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть скрипт Python в виде строки, например:

exec("sent = {'test': 1}")
global sent
print(sent)

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

class example:
    def fun1(self):
        exec("sent = {'test': 1}")
        global sent
        print(sent)

v = example()
print(v.fun1())

, я получаю следующую ошибку:

NameError: name 'sent' is not defined

Ответы [ 2 ]

0 голосов
/ 19 ноября 2018

Вы не передаете глобальный словарь для изменения.Попробуйте:

 exec("sent = {}",globals())
0 голосов
/ 19 ноября 2018

Вы действительно должны избегать использования глобальных переменных. В любом случае, вот как это сделать:

class example:
    def fun1(self):
#        globals sent  # Not needed in this special case.
        exec("sent = {}", globals())
        print('in fun1, "sent" is now', sent )


v = example()
print(v.fun1())  # Result will be None because fun1() doesn't return anything.
print('after call to fun1(), global "sent" is', sent)

Выход:

in fun1, "sent" is now {}
None
after call to fun1(), global "sent" is {}

Объявление global делает что-то только внутри метода функции или класса и даже тогда необходимо только тогда, когда значение глобальной переменной будет установлено на что-то. Однако, как особый случай, в методе fun1() он на самом деле не нужен, потому что он явно передает globals() (но не отдельный локальный запрос), когда он вызывает exec(). В любом случае, было бы неплохо добавить его, чтобы было более понятно, что происходит.

Использование exec() таким образом объясняется в его документации , которая гласит:

Если указываются только глобальные переменные, это должен быть словарь, который будет использоваться для как глобальной, так и локальной переменных.

(выделено мое)

Вот способ вообще не ссылаться на глобальную переменную в методе:

class example:
    def fun1(self):
        namespace = {}
        exec("sent = {}", namespace)
        sent = namespace['sent']  # Retrieve result.
        print('in fun1, "sent" is now', sent )
        return sent

v = example()
sent = v.fun1()
print('after calling fun1(), "sent" got set to', sent)

Выход:

in fun1, "sent" is now {}
after calling fun1(), "sent" got set to {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...