1

I am new to classes and writing one to perform a tracking and timing task. Have looked at this but still having trouble getting one aspect of the functionality to work.

Here's the part of what I've got to demonstrate the problem:

class seperate_trackers():

    def __init__(self): 
        print ("class initiated")

    def print_instance_name(self):
        print (self.__class__.__name__)

Create an instance of it:

track_task1 = separate_trackers()
>> class initiated

Run the method in there:

track_task1.print_instance_name()
>> separate_trackers

That's not what I want!

How can that method be fixed so it returns track_task1 when it is run?

cardamom
  • 6,873
  • 11
  • 48
  • 102
  • 1
    And what should `track_task1 = track_task2 = separate_trackers()` print? – Moses Koledoye Jun 15 '17 at 14:47
  • That would be really bad design. Furthermore it is possible that **multiple variables** assign to the same object. – Willem Van Onsem Jun 15 '17 at 14:47
  • I would not type that in. Why would I do that? – cardamom Jun 15 '17 at 14:48
  • Possible duplicate of [How can you print a variable name in python?](https://stackoverflow.com/questions/592746/how-can-you-print-a-variable-name-in-python) – Uriel Jun 15 '17 at 14:49
  • 1
    @cardamom I'm not saying you will. I only wanted to show that the class/instance is *blind* to the assignment. – Moses Koledoye Jun 15 '17 at 14:49
  • 1
    @cardamom: but that is not how it works: a good programming language aims to facilitate what is good design, and should aim to make it (close to) impossible what is not good design. Variable names are actually *identifiers*. A good program usually does *not* care about the specific names used. Only in some circumstances (like `kwargs`) is is good to do that. – Willem Van Onsem Jun 15 '17 at 14:50
  • @WillemVanOnsem Ok so you are saying even if you could modify that function you shouldn't? I just thought it would have been a convenient way to give each timer it's name.. – cardamom Jun 15 '17 at 14:51
  • 1
    To give a more kind answer: It doesn't and it shouldn't work. It's possible that many thousand variables, lists, dicts reference the same object all over the program - managing all of these would be a nightmare. The way they currently are, they're only one way, too - a variable points to an object, but the object has no connection per se to the variable. So: No. [Here's a way to do it](https://stackoverflow.com/questions/592746/how-can-you-print-a-variable-name-in-python), but **don't**. Better would be to initialize the class with it's name. This design is in fact in many packages. – Nearoo Jun 15 '17 at 15:01
  • _to initialize the class with a name_ Ok so the variable is just a handle, one of perhaps many (but why would you code more than 1 handle?) Anyway thanks I am understanding that you should not name your instance with the variable name. – cardamom Jun 15 '17 at 15:05
  • https://stackoverflow.com/questions/1690400/getting-an-instance-name-inside-class-init – suvy Jun 15 '17 at 15:06

3 Answers3

3

This is not a good idea. If you want your instance to have a name, that should be an attribute of the instance itself (the name of the variabe is just a pointer and it should not represent the object's state).

Try this instead:

# We don't usually use snake case for class names in python (and its 'separate')
class SeparateTrackers():

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


instance1 = SeparateTrackers("instance_name")

print(instance1.name) # instance_name
  • Thanks, that basically does it, but how do you get that print statement into a function `print_instance_name` inside the class like I did? Been experimenting with that but not yet worked it out. Thanks for the PEP 8 tips btw that's something else we need to know.. – cardamom Jun 15 '17 at 15:11
  • 1
    Just add this method to the class: `def print_instance_name(self): print(self.name)` – Prateek Sanyal Jun 15 '17 at 15:16
  • Yes that works! Thanks. I tried something like that but had (self, name) as the arguments of that print function which generated an error `TypeError: print_instance_name() missing 1 required positional argument: 'name'` Anyway, once you go back to just `self` in there it works. – cardamom Jun 15 '17 at 15:19
1

Objects don't know what variables refer to them. There can be any number of references to an object, and none of them is "the real one," they are all equally valid as names for the object. Furthermore, there may be no references that are simple names:

things = [1, "hello", separate_trackers(), 3.14]

There's no useful way to find out what variables refer to an object.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
1
class SeparateTrackers:
  def __init__(self, instance_name):
    self.instance_name = instance_name

  def __str__(self):
    return self.instance_name

So you can use something like

a = SeparateTracker("first instance")
print(a) # print instance's name
Emmanuel Mtali
  • 4,383
  • 3
  • 27
  • 53