Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 12, 2017 18:30:56

NotImplemented
Зарегистрирован: 2017-08-12
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Изменение локального пространства имен с помощью input()

Здравствуйте.
Я пытаюсь изменить значения аргументов функции, заданные по умолчанию, из командной строки с помощью функции input(). Я хочу сделать это именно так и знаю, что можно (возможно, даже нужно) сделать иначе. Тем не менее, интересно именно так. Я пробовал достать словарь, представляющий пространство имен функции изнутри самой функции при помощи

function_name.__dict__
, но это выражение возвращает пустой словарь. Также пытался использовать locals() вопреки запрету в официальной документации на изменение словаря, возвращаемого ею. Она ведет себя странным образом (см. приложенное изображение). Была мысль сделать это через eval() так:
 def defaults(a=11, b=22):
    for default in locals():
        eval('{0} = int(input({0}))'.format(default))  # пусть ключ служит подсказкой для ввода
но тут все тоже горит и рушится по непонятной причине (invalid syntax).
Можно ли как-то извернуться и все-таки сделать это (желательно не слишком уродливым образом)?

Отредактировано NotImplemented (Авг. 12, 2017 18:39:19)

Прикреплённый файлы:
attachment Снимок экрана от 2017-08-12 18-10-24.png (64,5 KБ)

Офлайн

#2 Авг. 12, 2017 18:49:50

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

Изменение локального пространства имен с помощью input()

Python второй, в третьем атрибуты другие

 >>> def foo(a=11, b=10):
...     print a, b
>>> foo()
11 10
>>> foo.func_defaults = (20, 30)
>>> foo()
20 30



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

Офлайн

#3 Авг. 12, 2017 19:49:51

NotImplemented
Зарегистрирован: 2017-08-12
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Изменение локального пространства имен с помощью input()

Rodegast вариант хороший, спасибо. Вот только этот атрибут возвращает кортеж, который, будучи неизменяемым, вынудит создать промежуточный объект для вводимых значений, ведь их надо получать от пользователя по одному, выводя подсказку на экран к каждому из них. Это эквивалентно созданию отдельного словаря внутри функции для хранения значений по умолчанию, что маленько не то, чего я хочу. Возможно, это и нельзя сделать.
Если я правильно понимаю, пространство имен реализовано в виде словаря. Обыконвенным присвоением в коде я могу добавлять в этот словарь записи. Но не выходит добавить их через input(), что не дает мне покоя. Ведь должен же быть способ, это же очевидная вещь. Может, это специально сделано так для защиты от дурака?

Офлайн

#4 Авг. 12, 2017 20:26:07

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

Изменение локального пространства имен с помощью input()

Не путай значение по умолчанию и пространство имён. С input - ом нет никакой проблемы.

 >>> def foo(a=11, b=10):
...     a = input("")
...     b = input("")
...     print a, b
...
>>> foo()
4
5
4 5



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

Офлайн

#5 Авг. 12, 2017 20:57:59

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Изменение локального пространства имен с помощью input()

NotImplemented
Если я правильно понимаю, пространство имен реализовано в виде словаря.
м-м- не совсем, у класса function есть атрибут __defaults__ в котором собственно и храняться значения по умолчанию. можно использовать func_defaults а можно напрямую , но поскольку кортежи неизменяемые обьекты то вам придеться каждый раз создавать новый кортеж и связывать его с атрибутом __defaults__
вобще достучаться до докального простарнства имен извне функции нельзя.
Можно получить словарь вызвав locals() внутри функции но любые изменения этого словаря не будут иметь никакого эффекта. Патамуша у каждого вызова функции оно своё, функция может выполняться одновременно в нескольких потоках каждый со своим локальным пространством имён, может вообще не выполняться и так далее…



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#6 Авг. 12, 2017 21:10:26

NotImplemented
Зарегистрирован: 2017-08-12
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Изменение локального пространства имен с помощью input()

Rodegast в твоем примере имена умолчаний захардкожены, плюс пришлось бы писать их в аргументе input()'а еще раз для подсказки. Функция же знает собственное пространство имен, в котором хранятся умолчания, зачем их переписывать по три раза? Надо только извлечь их имена и значения. Я хочу что-то вроде

  def defaults(a=11, b=22):
    for default in locals():
        exec('{0} = int(input({0}))'.format(default)) 
, но только чтобы format() подставлял не значения умолчаний, а их имена (в данном случае a или b), причем для input()'a - строку, содержащую имя, а для первого маркера {0} - само имя. Но цикл оперирует самим объектом, присваивая ему новое имя (в данном случае default). Методу format() в качестве аргумента передается по сути адрес в памяти, и он не знает ничего ни про какие имена. Досадно, ну да ладно.

Отредактировано NotImplemented (Авг. 12, 2017 21:43:36)

Офлайн

#7 Авг. 12, 2017 21:47:33

NotImplemented
Зарегистрирован: 2017-08-12
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Изменение локального пространства имен с помощью input()

PEHDOM
можно использовать func_defaults а можно напрямую , но поскольку кортежи неизменяемые обьекты то вам придеться каждый раз создавать новый кортеж и связывать его с атрибутом __defaults__
Да я это понял уже:
NotImplemented
Вот только этот атрибут возвращает кортеж, который, будучи неизменяемым, вынудит создать промежуточный объект для вводимых значений, ведь их надо получать от пользователя по одному, выводя подсказку на экран к каждому из них.
PEHDOM
Можно получить словарь вызвав locals() внутри функции но любые изменения этого словаря не будут иметь никакого эффекта.
Ага, про это я и пишу в первом сообщении в теме, только там не то что бы нет эффекта, а скорее эффект странный:
NotImplemented
Также пытался использовать locals() вопреки запрету в официальной документации на изменение словаря, возвращаемого ею. Она ведет себя странным образом (см. приложенное изображение).

Офлайн

#8 Авг. 12, 2017 22:00:05

PEHDOM
Зарегистрирован: 2016-11-28
Сообщения: 2196
Репутация: +  294  -
Профиль   Отправить e-mail  

Изменение локального пространства имен с помощью input()

NotImplemented
Ага, про это я и пишу в первом сообщении в теме, только там не то что бы нет эффекта, а скорее эффект странный:
он не странный, у вас в локальном пространстве имен три переменных, a и b которые являються аргументами функции и default которой вы передаете значения в цикле.



==============================
Помещайте код в теги:
[code python][/code]
Бериегите свое и чужое время.

Офлайн

#9 Авг. 12, 2017 22:11:40

NotImplemented
Зарегистрирован: 2017-08-12
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Изменение локального пространства имен с помощью input()

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

Отредактировано NotImplemented (Авг. 12, 2017 22:12:00)

Офлайн

#10 Авг. 13, 2017 10:02:23

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Изменение локального пространства имен с помощью input()

NotImplemented

 >>> a = 1
>>> b = eval('a') + 1 
>>> b
2



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version