Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Python для экспертов
  • » Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно? [RSS Feed]

#1 Авг. 18, 2019 13:45:43

MLM
Зарегистрирован: 2012-12-06
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?

Код:

 #!/usr/bin/env python3
# -*- coding: utf-8 -*-
def check_test():
    print('*globals().keys() не меняется ->', *globals().keys())
    print('    До всего')
    print('locals() ->', locals())
    print('dir() ->', dir())
    print('    До "exec"')
    print('a = 5')
    a = 5
    print('locals() ->', locals())
    print('dir() ->', dir())
    exec('''
print('    Внутри "exec"')
print('b = 3')
b = 3
print('locals() ->', locals())
print('dir() ->', dir())
print('a ->', a)
print('locals()["b"] ->', locals()['b'])
print('b ->', b)
        ''')  # , globals(), locals()
    print('    После "exec"')
    print('locals() ->', locals())
    print('dir() ->', dir())
    print('a ->', a)
    print('locals()["b"] ->', locals()['b'])
    print(end='b -> ')
    try:
        print(b)
    except Exception as e:
        print(e)
    exec('''
print('    Внутри второго "exec"')
print('b ->', b)
        ''')
    print('    После второго "exec"')
    print(end='b -> ')
    try:
        print(b)
    except Exception as e:
        print(e)
if __name__ == '__main__':
    check_test()
На выходе:
*globals().keys() не меняется -> __name__ __doc__ __package__ __loader__ __spec__ __builtins__ __file__ check_test
До всего
locals() -> {}
dir() -> []
До "exec"
a = 5
locals() -> {'a': 5}
dir() -> ['a']
Внутри "exec"
b = 3
locals() -> {'a': 5, 'b': 3}
dir() -> ['a', 'b']
a -> 5
locals()["b"] -> 3
b -> 3
После "exec"
locals() -> {'a': 5, 'b': 3}
dir() -> ['a', 'b']
a -> 5
locals()["b"] -> 3
b -> name 'b' is not defined
Внутри второго "exec"
b -> 3
После второго "exec"
b -> name 'b' is not defined

Отредактировано MLM (Авг. 21, 2019 08:20:04)

Прикреплённый файлы:
attachment test_eval.py (1,1 KБ)

Офлайн

#2 Авг. 18, 2019 15:07:57

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?

> Переменная, созданная в “exec”, недоступна после “exec”, хотя присутствует в dir() и locals(). Легализовать переменную Возможно?

Ну как бы:

 >>> exec("a=3")
>>> a
3
P.S. Никогда не используй exec.



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#3 Авг. 18, 2019 16:10:56

MLM
Зарегистрирован: 2012-12-06
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?

1. Спасибо за попытку помочь.
2. Перед тем как задавать вопрос, я всяко пробовал, и что в интерпретаторе работает знаю. Нормально тоже работает, если код в глобальной области. Но интересует именно вопрос “легализации” переменной в локальной области, согласно locals().
3. При использовании “exec”, код для него будет генерировать сама программа, т.е. ничего неожиданного не будет.
4. Правда, полученные значения переменных будут использоваться кодом функции “eval”, который написан своим человеком, не из Интернета. Но тем не менее, этот код будет пропущен через фильтр допустимых слов, что должно обезопасить от возможных неожиданностей.
5. Может подскажете ещё какие то меры.

Офлайн

#4 Авг. 18, 2019 17:07:05

FishHook
От:
Зарегистрирован: 2011-01-08
Сообщения: 8312
Репутация: +  568  -
Профиль   Отправить e-mail  

Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?

 def foo():
    exec("a=1", {}, locals())
    print(locals())
foo()



Офлайн

#5 Авг. 18, 2019 17:31:37

MLM
Зарегистрирован: 2012-12-06
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?

Спасибо за попытку помочь. О доступе через locals() знаю. В коде есть строка

     print('locals()["b"] ->', locals()['b'])
Передать вместо globals() пустой словарь - хорошая идея, но тогда даже такой код нельзя использовать:
     exec('''
globals()["b"] = b
        ''')
Хотя после него переменная уже доступна и значение её правильное, но она глобальная.
Но интересует именно вопрос “легализации” переменной “b” в локальной области, согласно locals(), если это вообще возможно.

Отредактировано MLM (Авг. 18, 2019 17:53:03)

Офлайн

#6 Авг. 18, 2019 17:42:54

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?

 >>> def foo():
...     s = {}
...     exec("a=1", {}, s)
...     print(s.get('a'))
...
>>> foo()
1



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#7 Авг. 18, 2019 17:52:21

MLM
Зарегистрирован: 2012-12-06
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?

Надо чтобы

     print(b)
работало. Что бы “b” было в локальной области, если это возможно.

Офлайн

#8 Авг. 18, 2019 18:11:44

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?

> Что бы “b” было в локальной области, если это возможно.

 b = s.get('a')



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#9 Авг. 18, 2019 18:22:43

MLM
Зарегистрирован: 2012-12-06
Сообщения: 9
Репутация: +  0  -
Профиль   Отправить e-mail  

Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?

С переменной “a” проблем нет, с “b” проблемы

     b = locals()['b']
#    b = s['b']  # будет тоже самое
KeyError: 'b'
Похоже, сделать доступной локальную переменную “b” из “exec” в локальной области “check_test” невозможно.

Отредактировано MLM (Авг. 18, 2019 18:24:17)

Офлайн

#10 Авг. 18, 2019 18:34:15

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2679
Репутация: +  182  -
Профиль   Отправить e-mail  

Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?

> С переменной “a” проблем нет, с “b” проблемы

Ну так и быть…

 >>> def foo():
...     s = {}
...     exec("b=3", {}, s)
...     b = s.get('b')
...     print(b)
...
>>> foo()
3



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

  • Начало
  • » Python для экспертов
  • » Переменная, созданная в "exec", недоступна после "exec", хотя присутствует в locals(), vars() и dir(). Легализовать переменную Возможно?[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version