Найти - Пользователи
Полная версия: Изменение локального пространства имен с помощью input()
Начало » Python для новичков » Изменение локального пространства имен с помощью input()
1 2
NotImplemented
Здравствуйте.
Я пытаюсь изменить значения аргументов функции, заданные по умолчанию, из командной строки с помощью функции 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).
Можно ли как-то извернуться и все-таки сделать это (желательно не слишком уродливым образом)?
Rodegast
Python второй, в третьем атрибуты другие
 >>> def foo(a=11, b=10):
...     print a, b
>>> foo()
11 10
>>> foo.func_defaults = (20, 30)
>>> foo()
20 30
NotImplemented
Rodegast вариант хороший, спасибо. Вот только этот атрибут возвращает кортеж, который, будучи неизменяемым, вынудит создать промежуточный объект для вводимых значений, ведь их надо получать от пользователя по одному, выводя подсказку на экран к каждому из них. Это эквивалентно созданию отдельного словаря внутри функции для хранения значений по умолчанию, что маленько не то, чего я хочу. Возможно, это и нельзя сделать.
Если я правильно понимаю, пространство имен реализовано в виде словаря. Обыконвенным присвоением в коде я могу добавлять в этот словарь записи. Но не выходит добавить их через input(), что не дает мне покоя. Ведь должен же быть способ, это же очевидная вещь. Может, это специально сделано так для защиты от дурака?
Rodegast
Не путай значение по умолчанию и пространство имён. С input - ом нет никакой проблемы.
 >>> def foo(a=11, b=10):
...     a = input("")
...     b = input("")
...     print a, b
...
>>> foo()
4
5
4 5
PEHDOM
NotImplemented
Если я правильно понимаю, пространство имен реализовано в виде словаря.
м-м- не совсем, у класса function есть атрибут __defaults__ в котором собственно и храняться значения по умолчанию. можно использовать func_defaults а можно напрямую , но поскольку кортежи неизменяемые обьекты то вам придеться каждый раз создавать новый кортеж и связывать его с атрибутом __defaults__
вобще достучаться до докального простарнства имен извне функции нельзя.
Можно получить словарь вызвав locals() внутри функции но любые изменения этого словаря не будут иметь никакого эффекта. Патамуша у каждого вызова функции оно своё, функция может выполняться одновременно в нескольких потоках каждый со своим локальным пространством имён, может вообще не выполняться и так далее…
NotImplemented
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
PEHDOM
можно использовать func_defaults а можно напрямую , но поскольку кортежи неизменяемые обьекты то вам придеться каждый раз создавать новый кортеж и связывать его с атрибутом __defaults__
Да я это понял уже:
NotImplemented
Вот только этот атрибут возвращает кортеж, который, будучи неизменяемым, вынудит создать промежуточный объект для вводимых значений, ведь их надо получать от пользователя по одному, выводя подсказку на экран к каждому из них.
PEHDOM
Можно получить словарь вызвав locals() внутри функции но любые изменения этого словаря не будут иметь никакого эффекта.
Ага, про это я и пишу в первом сообщении в теме, только там не то что бы нет эффекта, а скорее эффект странный:
NotImplemented
Также пытался использовать locals() вопреки запрету в официальной документации на изменение словаря, возвращаемого ею. Она ведет себя странным образом (см. приложенное изображение).
PEHDOM
NotImplemented
Ага, про это я и пишу в первом сообщении в теме, только там не то что бы нет эффекта, а скорее эффект странный:
он не странный, у вас в локальном пространстве имен три переменных, a и b которые являються аргументами функции и default которой вы передаете значения в цикле.
NotImplemented
PEHDOM точно, вы правы. Будь у меня способ преобразовать строку, содержащую имя переменной в само имя переменной, и я бы заставил программу работать именно так, как хочу.
JOHN_16
NotImplemented
 >>> a = 1
>>> b = eval('a') + 1 
>>> b
2
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB