Wednesday, March 23, 2011

Addressing instance name string in __init__(self) in Python.

I am doing something like this:

class Class(object):
    def __init__(self):
        self.var=#new instance name string#

How do I make the __ init __ method of my instance to use the instance name string for 'c'? Say in case:

c=Class()

I want c.var equal to 'c'.

Thanks for your replies, I am implementing persistence and Class is persistent object's class. I want __ init __ to add an entry to the database when:

c=Class()

Then, suppose:

del c

Later on:

c=Class()

sholuld create an instance using data from database if there already is an entry 'c', otherwise create new entry.

From stackoverflow
  • That isn't possible. You seem to be confusing variables and objects.

    In any case there may well not be a variable:

    e.g.

    foo(Class())
    
    Class().arbitraryMethod()
    

    Or multiple:

    a = b = Class()
    
  • I am unaware of a way to access a variable's name programmatically without using deep reflection and a debugger. I do not think the information is available at runtime.

    If you want to give instances a (unique?) name, you should probably make the initializer accept an extra argument.

    def __init__(self, name):
        self.name = name
    

    And the caller should pass in the appropriate name:

    c = Class("c")
    
  • You can't (short of incredible hacks like examining the stack frame and inspecting the bytecode). There may not even be a name, or there could be multiple such names. What should be given for the following code fragments for instance:

    l = [Class(), Class()]
    a=b=c=d=Class()
    
  • I don't think this would be possible because the assignment to the variable of your new instance occours after the object is fully constructed and initialized and so you don't know the variable name it will be assigned to within init method

  • You can't do this. The reason for this is that the object of the class is created first, and only afterwards is this object bound to the name of the instance.

  • This is a scope issue, you can't do what you're asking. Because c would be declared outside your class' scope, your instance is unaware of what its been named in code.

    Perhaps if you can provide a broader explanation of what you're trying to accomplish a better solution can be suggested.

  • Python doesn't have variables, it has objects and names. When you do

    c = Class()
    

    you're doing two things:

    1. Creating a new object of type Class
    2. Binding the object to the name c in the current scope.

    The object you created doesn't have any concept of a "variable name" -- If later you do

    a = c
    

    then the same object is accessible in exactly the same way using the names a and c. You can delete the name a, and the object would still exist.

    If the objects you create need to have a name, the best way is to pass it to them explicitly,

    class Class(object):
        def __init__(self, name):
            self.name = name
    
    var = Class('var')
    
  • Thanks for your replies, I am implementing persistence and Class is persistent object's class. I want __ init __ to add an entry to the database when:

    c=Class()
    

    Then, suppose:

    del c
    

    Later on:

    c=Class()
    

    sholuld create an instance using data from database if there already is an entry 'c', otherwise create new entry.

    bobince : You would have to pass the 'c' (or other, more unique, identifier) in explicitly - probably better than doing it with magic anyway. There is magic that could detect bound names if you wrapped the whole thing up in a class with a metaclass, but it's definitely worse than just doing it manually here.
    S.Lott : This is not an answer. This is more of your question. Please update your question with these additional facts.
  • To persist data objects you need to use the database record's unique ID.

    pesudo code because I don't know what database module you're using

    import db # assume this is your db module
    
    class Class(object):
        def __init__(self):
            self.id = None
            self.name = None
    
        def get_by_id(self, id):
            records = db.execute('select * from table where id=%s' % str(id))
            if records:
                self.id = records[0]['id']
                self.name = records[0]['name']
    
        def save(self):
            db.execute('update table set name=%s where id=%s' % (self.name, str(self.id)))
    

    Again, this is pseudo code, the string injection technique I'm using is NOT advised as its fairly insecure, its just there to illustrate how to persist using classes with a db.

  • I have the same thought several years ago. This is somekind of neat feature, but the language creator doesn't provide it. And I thought they are all fool to not discover this great feature.

    But then come to think about that. I think the logic is impossible. say:

    class Class(object): def init(self): self.instance_name.move() # self.instance_name refer to var def move(self): print "move"

    var = Class()

    now if the var is an array is that possible too ?

    var[0] = Class() # i think it will get confused a bit

    that's what i think of, i don't think that assigning the instance into itself is possible. and in some language I just sent the instance string into the object then using eval to execute the function

0 comments:

Post a Comment