2

I have something like

def myfunc(list):

When I call the function, I can type like

myfunc(List1)

There is a way to print out the list typed as argument in the function? Something like:

def myfunc(list):
    print (list.name)

That would give:

myfunc(List1)
List1

Thank you in advance

Niccolò
  • 169
  • 2
  • 8
  • 2
    No. The name of the variable is not an attribute of the variable itself. You might be able to get there with inspect, but it will be a challenge -- https://docs.python.org/2/library/inspect.html – user590028 Jul 18 '15 at 16:46
  • 1
    What if you call your function with `myfunc([1,2,4])`, which name would you expect? – Daniel Jul 18 '15 at 16:59
  • What are you *actually* trying to achieve? – jonrsharpe Jul 18 '15 at 17:44

3 Answers3

0

It is possible, you can find it inside func_globals which is a dictionary, the problem is that the s is the ky and 4 is the value. and i know the value of param, so what is did is search key in dictionary by a given value

def fun(param):
    print fun.func_globals.keys()[fun.func_globals.values().index(param)]
s = 4
fun(s)

'[OUT]': s

this is func_globals:

print fun.func_globals
'[OUT]': {'__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:/Users/omri/PycharmProjects/mailer/ff/__init__.py', '__doc__': None, 's': 4, 'fun': <function fun at 0x0049F4F0>, '__name__': '__main__', '__package__': None, 'izip_longest': <type 'itertools.izip_longest'>}
omri_saadon
  • 10,193
  • 7
  • 33
  • 58
  • what if you had two params with the same value? – Pynchia Jul 18 '15 at 16:55
  • actually, that is a problem.. can you think on a soluion? – omri_saadon Jul 18 '15 at 16:56
  • There is no solution, because both names point to the absolutely same object. – Daniel Jul 18 '15 at 16:58
  • Nope. I am quite amused by your solution actually. I'd never thought the function had access to the name that refers to an object passed to it. And I do not know why that happens, BTW. I thought names and objects were disjoint. – Pynchia Jul 18 '15 at 17:00
  • A solution i can think of is if functions has always the same keys in the func_globals, then the only thing that change is the parameters keys. Although i'm not sure if thats correct. – omri_saadon Jul 18 '15 at 17:00
  • 1
    @Pynchia: `func_globals` is the namespace of the module, the function is defined. So if you call `fun` from a function or from another module, the solution won't work either. – Daniel Jul 18 '15 at 17:04
0

If your objective is to print the actual list (the argument that you pass) here's the code:

def myfunc(list1):
 print list1 #prints the actual list
myfunc([1,2,34,5])
[1,2,34,5] #result

otherwise if you are looking to print the arg name, the above answers could help you.

amrrs
  • 6,215
  • 2
  • 18
  • 27
0

A variant over the one suggested by omri-saadon, is to use inspect.getframeinfo which lists the code_context.

import inspect

def debug(*args):

    try:  # find code_context

        # First try to use currentframe() (maybe not available all implementations)
        frame = inspect.currentframe()
        if frame:
            # Found a frame, so get the info, and strip space from the code_context
            code_context = inspect.getframeinfo(frame.f_back).code_context[0].strip()
        else:

            # No frame, so use stack one level above us, and strip space around
            # the 4th element, code_context
            code_context = inspect.stack()[1][4][0].strip()

    finally:
         # Deterministic free references to the frame, to be on the safe side
         del frame

    print('Code context: {}'.format(code_context))
    print('Actual arguments: {}'.format(args))


## Test code to have something to output #########
def my_seventh():
   return 7

a = 0.2
b = 1.2
c = a + 1
my_eight = my_seventh

debug(a, b, c, b+2)
debug([4.1, 4.2], (5.1, 5.2), {6.1: 6.2}, my_seventh, my_eight, my_eight())

my_list = [1, 2, 3, 4, 5]

def first_level():
    def second_level():
         debug(my_list[:2],
               my_list[3:])

    second_level()

first_level()

Output when running this code is:

Code context: debug(a, b, c, b+2)
Actual arguments: (0.2, 1.2, 1.2, 3.2)
Code context: debug([4.1, 4.2], (5.1, 5.2), {6.1: 6.2}, my_seventh, my_eight, my_eight())
Actual arguments: ([4.1, 4.2], (5.1, 5.2), {6.1: 6.2}, <function my_seventh at 0x102294488>, <function my_seventh at 0x102294488>, 7)
Code context: my_list[3:])
Actual arguments: ([1, 2], [4, 5])

In other words, using the inspect options to get the frameinfo will give you the source line (or last line thereof) which triggered your function call. However if the actual call is split over multiple lines, only the last line is given as code context. And so far I've not found a way to connect the named variables in the code context to the actual arguments.

holroy
  • 3,047
  • 25
  • 41