1

I know this is a weird idea. The idea would be something like this:

class AnyClass:
    def __init__(self):
        # print object name

Then create a new object

test = AnyClass()

And finally get this output:

'test'

That is not the idea behind this, but is an easy example of what I'm trying to...

PS: I'm not trying to get the class name, just the object name (if possible) PS2: I know I can get the name with test.__name__ but I'm trying to get the name inside the class, not outside.

Brendan Abel
  • 35,343
  • 14
  • 88
  • 118
  • You want the variable name that references to the object? How would the class know what variable it is assigned to? – OneCricketeer Mar 29 '16 at 16:31
  • 6
    Objects do not have names; names refer to objects. – zondo Mar 29 '16 at 16:31
  • `test` object does not exist at the time `AnyClass()` and as `test` does not exist when `__init__()` is called, I don't think there is a way for it to know its name. – licorna Mar 29 '16 at 16:33
  • @cricket_007 I don't know... I guess it is not possible :( – Edu Roldan Pijuan Mar 29 '16 at 16:33
  • Local variable names are not stored anywhere except as references to memory locations within the Python interpreter; since these names are assigned memory locations at runtime, and Python has no meta-interpretive abstraction, I think this is not possible. – manglano Mar 29 '16 at 16:34
  • @licorna That's what I thought, but would fine to check the name of the object when it is created to check if the name follows some rules for example. – Edu Roldan Pijuan Mar 29 '16 at 16:35
  • What if you have two variables referencing the same object? – coredump Mar 29 '16 at 16:35
  • 2
    I guess this would be possible by looping over locals looking for a reference to the class in question (optionally descending into containers) but whatever is making you think this is necessary, just rethink it. – Two-Bit Alchemist Mar 29 '16 at 16:35
  • 3
    what would you expect for `x= test = yellow = MyClass()` ? – Joran Beasley Mar 29 '16 at 16:38
  • This is almost certainly an [XY problem](http://meta.stackexchange.com/a/66378). Ask another question describing what you are actually trying to do. – Rick Mar 29 '16 at 17:07
  • 1
    The object name, at the place you have commented, is 'self' and that's the only name you need to know at that point – wim Mar 29 '16 at 17:36

2 Answers2

3

Consider this:

>>> a = dict()
>>> b = a

Both a and b reference the exact same object.

>>> a is b
True

When you do a . operation on an object, you're looking up an attribute on that object. An object can be referenced in many different locations; it makes no sense for it to store all those reference names, especially when those names are only bound within certain contexts. For example

def generator():
    a = dict()
    yield a

b = next(generator())

Both a and b refer to the same dict object, but you can't use a to reference the dict anywhere else besides in the generator function.

Within a specific context, you can test the bound names and see if they refer to a specific object.

test = MyObject()

for name, obj in locals().items():
    if test is obj:
        print name
zondo
  • 19,901
  • 8
  • 44
  • 83
Brendan Abel
  • 35,343
  • 14
  • 88
  • 118
1

First: you don't want to do this, there is no reason to do this, and if you think you need to do this, you're wrong.

Second: you can't do it in the __init__ method because the name reference test referring to the new AnyClass instance object hasn't been added to the memory space ("bound") yet. However, you could do it like this.

class AnyClass():
    def echo_name(self):
        {v:k for k,v in locals().items()}[self]

test = AnyClass()
test.echo_name()

This will return the first variable encountered in the locals() dictionary that is assigned to the test object. There is no guarantee for the order in which those variables will be returned.


To explain a bit further about why it won't work in the __init__ method, when you do this:

test = AnyClass()

A new instance of AnyClassis constructed according to the instructions of the class definition (including the definitions of any parent or metaclass). This construction happens in phases, the last phase of which is executing the __init__ method. Prior to __init__, other methods that will be executed, if they exist, are __new__, and also the the __new__, __init__, and __call__ methods of the metaclass (if one exists).

So at the point in time the code in the body of the __init__ method is being executed, the object is still being constructed. Therefore there is, as of yet, nothing in the locals() dictionary assigned to the name 'test'. There is only a member called 'self'. And, obviously, if you reverse-lookup the self object in the locals() dictionary looking for a registered name, the name you will get is the name 'self'. Which... isn't useful.

Rick
  • 43,029
  • 15
  • 76
  • 119
  • 1
    I think you mean `[self]`, not `[test]`. This is supposed to be in the `__init__()` method. I don't think that it will work anyway, though. – zondo Mar 29 '16 at 17:22
  • @zondo I missed that it is in the `__init__` method - you're right, won't even work. – Rick Mar 29 '16 at 17:24