TAGS :Viewed: 4 - Published at: a few seconds ago

[ Python: Referring to any created object with __init__ ]

Am building a program in which i use the constructor method in a class. My method looks like this:

class Myclass:
    population = 0
    def __init__(self, var1, var2, var3):
        Myclass.population +=1
        self.var1 = var1
        self.var2 = var2
        self.var3 = var3
        popFile = open('pop.txt', 'wt')
        popFile.write('population = ' + str(int(Myclass.population)))
        print('again blablabla')
        pliada = (var1, var2, var3)
        outFile = open('prog.txt', 'at')
        outFile.write(str(pliada) + '\n')

My problem is that in the above

outFile.write(str(pliada) + '\n')

I want to save apart from the tuple, the objects name! What else should I add inside the write() func?

For example when I run the program, i type:

First = Myclass('firstvar','secondvar','thirdvar')

and when i use


it only prints the above tuple. When I open prog.txt, again its only the tuple there. How can I refer to each object's name (am constructing) so that instead of saving ('firstvar','secondvar',thirdvar') my program will save First ('firstvar','secondvar',thirdvar'), where First is the var I entered to the program?


Answer 1

At object creation time, an object does not have a name. In fact, having a name is fundamentally not how Python's type system functions, although modules, types and functions are created with __name__ attributes.

In [12]: compile("First = Myclass('firstvar','secondvar','thirdvar')", "sample", "single")
Out[12]: <code object <module> at 0xf5fde458, file "sample", line 1>

In [14]: dis.dis(Out[12])
  1           0 LOAD_NAME                0 (Myclass)
              3 LOAD_CONST               0 ('firstvar')
              6 LOAD_CONST               1 ('secondvar')
              9 LOAD_CONST               2 ('thirdvar')
             12 CALL_FUNCTION            3
             15 STORE_NAME               1 (First)
             18 LOAD_CONST               3 (None)
             21 RETURN_VALUE

Note that the name First has not appeared at all until after Myclass is called using CALL_FUNCTION. The object returned by Myclass therefore has no clue about the existence of First (indeed, it doesn't exist until after the assignment STORE_NAME). The only way it could be found would be some insane black magic by tracing back the stack to find at what point the caller called the constructor and then interpret the future execution to find the name; and it is not guaranteed to even exist, let alone be as easy to understand as this sample.

What your object has, however, is an identity. Identities are not universally unique, but while the object exists, no other object has the same identity within the same process. You could find that identity using id(self), and the default stringification also includes it: str(f) produces things like <__main__.Foo instance at 0xf603f46c> (names of the module and class, while the instance id is printed in hexadecimal).

Once the name does exist, it is not a property of your object, but an entry in the namespace of the executed code (might be a module or a function call). It can equally be assigned into any other similar entries, such as attributes of other objects, and none of them are particularly authoritative; each points to the same unnamed object.

If you do want to name your objects, the easiest way is to simply pass a name to the creation, as with all your varN attributes.

Answer 2

In a comment you wrote:

Well my purpose on this program is to create people with 3 characteristics. For example: Yann = PeopleClass('Tall', 'Thin', 33)

If you want the name "Yann" to be a property of the person, you should include it as an attribute of the object (and probably pass it as an argument to the constructor), rather than using it as a variable name. Variable names should not be data!

Not all objects are bound to a variable with a simple name. For instance, if you have a list of people, you could access them through identifiers like people_list[0] and people_list[1]. Those wouldn't be too attractive to print out though! Similarly, a single object may be bound multiple times in variables with different names. If after you ran the code in your above comment, you did John = Yann, the same PersonClass instance could be reached through the variables Yann and John, and your code would have a very hard time knowing which was being used at any given moment.

So, rather than:

Yann = Person("Tall", "Thin", 33)


my_person = Person("Yann", "Tall", "Thin", 33)

(And of course, update the class definition to accept and store the name being passed in.)

Answer 3

I think the only way you could do it is to pass the name of object as another parameter to init method.

First = MyClass("First", "first_var", "second_var", "third_var")


self points to the object that has created it

self + str(pliada) + '\n'