LINUX.ORG.RU

Python: передать в функцию имя и значение переменной


0

1

Возможно ли как-то передать в функцию переменную так, чтобы передать не только значение, но и имя передаваемой переменной? Например:

var1 = 17

showNameAndMeaning(var1)

var1 = 17


Долго копался со всякими %s и %d, но здравый выход так и не пришел в голову.



Последнее исправление: ghostmansd (всего исправлений: 1)

Ответ на: комментарий от baverman

Да, моя промашка. Пошерстил в гугле, нашел вот такой вариант:

def my_func(arg, vars):
    mvar = [key for key, val in vars.items() if val==arg][0]
    print mvar+' = ',arg

test=123
my_func(test, vars())
jerrylee
()
Ответ на: комментарий от jerrylee

Для одинаковых значений, правда, выдается первое найденное.

jerrylee
()
Ответ на: комментарий от jerrylee

Oops

>>> def my_func(arg, vars):
...     mvar = [key for key, val in vars.items() if val==arg][0]
...     print mvar+' = ',arg
... 
>>> test=123
>>> my_func(test, vars())
test =  123
>>> test2=123
>>> my_func(test, vars())
test2 =  123
>>>
baverman ★★★
()

Мда, лоровские питонщики всё сплошь ламеры энтерпрайзные. Хотя, пожалуй, baverman более-менее вменяем.

>>> x = 15
>>> def bar(var):
...    for k, v in globals().items():
...        if id(var) == id(v):
...            print k, '=', v
...            
>>> bar(x)
x = 15
>>>  
Тормозно, да.

anonymous
()
Ответ на: комментарий от anonymous
>>> x = 15
>>> y = 15
>>> def bar(var):
...    for k, v in globals().items():
...        if id(var) == id(v):
...            print k, '=', v
...            
>>> bar(x)
x = 15
y = 15
>>>  

я молчу уж о случаях когда переменные определены локально в какой нить ф-ии, или когда bar определена не в том модуле где идет работа с переменными. Что бы дорасти до baverman-а Вам надо удалить злокачественно опухшее ЧСВ, глядишь на его место влезет че нить полезное...

AIv ★★★★★
()

Шикарная постановка задачи!

foo = 42

def bar(baz):
    …

bar(foo)

Вот внутри bar, какое имя имеет переменная, foo или baz?

Zenom ★★★
()
Ответ на: комментарий от AIv

Я, уважаемый, если Вы соизволите внимательнее перечитать мой комментарий, отпустил шпильку как раз не в адрес baverman, до чьего уровня мне предложено дорасти, а в сторону всех остальных питонщиков, засветившихся в треде. Вы, вроде бы тоже оказались в их числе, поэтому фимиаму, льющемуся с Ваших строк, я не удивляюсь. Также обращаю Ваше внимание, что прямого и полностью удовлетворяющего ответа дано не было, поскольку его и быть не может. Так что ограниченность моего варианта изначально подразумевалась. Ну и, конечно, я не буду пояснять такому кулхацкеру и гуру, как Вы, что Python кэширует первую сотню (могу соврать) целых чисел ввиду их большой среднестатистической используемости, чтобы их быстрее отдавать. Если попробовать на числах больших, там уникальность сохраняется. Хотя другой косяк вылазит. :) Ну так я уже оговорился выше по этому вопросу. А за моё ЧСВ не беспокойтесь - опухоль доброкачественная.

anonymous
()
Ответ на: комментарий от anonymous

В Вашем комментарии сначала была шпилька в торону всех питонщиков, а потом была попытка решения задачи о нахождении индентификатора переменной по ее значению - эта задача без анализа кода вызова ф-ии для питона заведомо некорректна, а приведенное Вами решение вдвойне некорректно потому что использует globals. Если Вы считаете свое ЧСВ доброкачественным, то надо было лезть вверх по стеку и парсить вызов bar (как это предалагал boverman если не ошибаюсь), или уж если хочется неоднозначностей то работать с id, но опять таки в верхнем кадре стека. Или если это для Вас слишком сложно, то ЧСВ спрятать и шпилек не отпускать - тогда бы не было вопросов...

AIv ★★★★★
()
Ответ на: комментарий от AIv

Лезть в стек? Чтобы подвергнуться обструкции со стороны всяких лисперов, ага. Тем паче это не pythonic, выглядит грязно и применимо только в хаковых модулях типа inspect. И о каких таких неоднозначностях id идёт речь?

anonymous
()
Ответ на: комментарий от anonymous

Лично мне пофик как это выглядит и что по этому поводу думают лисперы - мне важно что это работает и позволяет в итоге делать код проще.

Неоднозначности id очевидны - любое кол-во идентификаторов может ссылаться на один и тот же объект, поэтому найти по id конкретный идентификатор переданный в качестве аргумента ф-ии невозможно. Напр

a = b = c = d = e = f = []

bar(f)

AIv ★★★★★
()
Ответ на: комментарий от ghostmansd

хочу записывать в файл переменные в виде «VarName=VarMeaning», каждое с новой строки, а потом при необходимости их оттуда считывать. <...> Может, есть способ поэлегантнее?

Есть, можно этот файл импортировать

alix ★★★★
()
Ответ на: комментарий от alix

Вот есть файл config.py, а в нем:

a = 2
b = 3
c = "I've got big balls"
А в файле, где они используются просто писать
import config

alix ★★★★
()
Ответ на: комментарий от Zenom

Это шутка? В Python оперируют не переменными, а объектами; переменные лишь ссылки на них. Так что ваш вопрос лишен смысла ещё более чем вопрос ТС.

anonymous
()
Ответ на: комментарий от alix

Прочитай уже тред. Сабж не об этом.

anonymous
()
Ответ на: комментарий от anonymous

O_O???? Второй вменяемый анонимус на ЛОРе... ;-)

AIv ★★★★★
()

Ладно, все варианты уже разжевали, лично я в аналогичных задачах делаю примерно так:

def dump( *vars ) :
    vars = sum( map( str.split, vars ), [] ) #бьем строки по пробелам и сливаем все в один список
    fr = sys._getframe(1)
    for v in vars : print '%s = %r'%( v, fr.f_locals[v] if v in fr.f_locals else fr.fr_global[v] )
...
a, b, c = 1, 2, 3
dump( 'a b', 'c' )

Все равно надо имена переменных передавать как строки, а возможность все загнать в одну строку через пробел банально экономит символы. Обратите внимание на форматирование по %r - это позволяет корректно приводить к строке и разные типы.

Иногда удобно использовать пылесос, который достает все из текущего кадра, что не попадает в список ignore, имеет простые типы и не начинается c _:

def dump( *ignore ) :
    ignore = sum( map( str.split, ignore ), [] ) #бьем строки по пробелам и сливаем все в один список
    fr = sys._getframe(1)
    for k, v in sorted( fr.f_locals.items() ) : 
         if k[0]!='_' and k not in ignore and type(v) in ( bool, str, int, long, float, complex, type(None) ) : 
              print '%s = %r'%( k, v )
...
a, b, c = 1, 2, 3
dump( 'b' ) # только a и b

Вместо тупого перечисления того чего не надо(надо) достать, можно использовать строки-шаблоны и обрабатывать их модулем fnmatch

AIv ★★★★★
()
Ответ на: комментарий от baverman

We enjoy our python with a great pleasure.

В чем же тут pleasure, 20 строк ковыряния змеиных кишков, да еще небось и между реализациями не переносимо.

cvb
()
Ответ на: комментарий от anonymous

И что? У переменных-ссылок есть имена. На один объект может ссылаться несколько переменных с разными именами.

Zenom ★★★
()
Ответ на: комментарий от anonymous

> Ну и, конечно, я не буду пояснять такому кулхацкеру и гуру, как Вы, что Python кэширует первую сотню (могу соврать) целых чисел ввиду их большой среднестатистической используемости, чтобы их быстрее отдавать

Поясни это мне. В частности, скажи, как это проверить. «Кэширование» целых - это фишка Явы, а про Питон впервые слышу.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

>> Но лиспер ее не решил.

Нет, решил, и гораздо более общим способом

Он решил какую-то другую задачу. Конечно, общим способом - макры же!!11

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Как я уже сказал, про конкретный диапазон могу соврать. Тем более для разных версий границы диапазона отличаются.
AIv пример продемонстрировал.
По идее при выполнении кода
x = 15
y = 15
должны создаваться два целых числа 15. А на деле id(x) равен id(y) (или x is y). В то же время, например,

y = 150

x = 150


x is y


0



Многие встроенные функции например возвращают -1. Так что диапазон кэширования захватывает и отрицательные числа.
Опять же конкретные цифры искать лень.
Не скажешь же ты, что не знал этого? :)

anonymous
()
Ответ на: комментарий от anonymous

Да, я уже догадался сравнить id :) Теперь думаю, чем чревато такое кэширование. С Явой всё ясно, а в Питоне оператор «==» отрабатывает нормально и на не-кэшируемых объектах, так что хз кому такое поведение опасно.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

> Он решил какую-то другую задачу.

Не «какую-то другую», а более общую. Надмножество исходной задачи. Что не так?

anonymous
()
Ответ на: комментарий от tailgunner

Оператор == наск я помню вообще вещь в себе (для пользовательских классов) - если он не перегружен то сравнивать будет как раз id.

С другой стороны, я наступал на грабли с is когда в хитроперекрученном коде не срабатывало None is None.

Вроде как и строки кэшируются (во всяком случае все идентификаторы), и есть еще встроенная ф-я intern

AIv ★★★★★
()

Похоже, это - единственный краткий выход (если, конечно, делать не на лиспе):

def configWrite(name):
  means = eval("%s" % name)
  print name, means

x = 15
y = 15
z = "baba"
x1 = [x, y, z]
configWrite("x")
configWrite("y")
configWrite("z")
configWrite("x1")

ghostmansd
() автор топика
Ответ на: комментарий от ghostmansd

В общем, большое всем спасибо! Вопрос можно считать решенным.

ghostmansd
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.