Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you get the instance variable name from a class? [duplicate]

I understand that you should never use variable names within the program, but I am using is strictly for debug purposes and would like to convey the name of the variable to the user for readability.

I have a file like this:

class MyClass(object):
    def __init__(self):
        pass

    def foo(msg=""):
        debug("Called from the %s instance.") #quazi-print function that only prints when a DEBUG variable is True.
        print(msg)

m = MyClass()
m.foo("Test")

I would like to retrieve the m instance variable name from within the class itself. Though this is merely an example file, I am using it to convey to the user that a raw socket has been created at a certain attribute within an instance variable, and would like to show where it is (i.e. New socket at m.socket)

Is this feasible with Python?

like image 788
Goodies Avatar asked Aug 23 '15 05:08

Goodies


2 Answers

You could look in the instance's globals dictionary and find the item that has its self as a value.

class Foo(object):
    def bar(self):
        return [k for k,v in globals().items() if v is self]
    def bah(self):
        d = {v:k for k,v in globals().items()}
        return d[self]

f = Foo()
g = Foo()

print f.bar(), g.bar()
print f.bah(), g.bah()

>>> 
['f'] ['g']
f g
>>> 
like image 56
wwii Avatar answered Oct 07 '22 23:10

wwii


Here's a really silly way to do it, if you don't mind the program exiting at that point: add this line to foo():

print undefined_variable

And when you get there, you get a stack trace like this:

Traceback (most recent call last): File "test.py", line 15, in <module> m.foo("Test") File "test.py", line 11, in foo print undefined_variable NameError: global name 'undefined_variable' is not defined

...which tells you that the name of the variable that called it was 'm' :)

(You might be able to do something like this using the traceback module, without killing the program. I've tried a few ways, but haven't managed to get it to include the m.foo() line in the output.)

like image 32
Felix Avatar answered Oct 08 '22 00:10

Felix