Re: Question re class variable
On Tue, 29 Sep 2015 02:27:23 -0700, plewto wrote: > I have a perplexing problem with Python 3 class variables. I wish to > generate an unique ID each time an instance of GameClass is created. > There are two versions of the __gen_id method with test run results for > each listed below the code. > > Originally I used the version which is now commented out. When a new > instance was created it created an ID by appending the value of > __instance_counter to the class name, it then checked the contents of of > __instatance_registrty to see if this ID was already in use. If so it > incremented the counter until it found an unused ID. This version works > exactly as I expected. > > Later I decided to get rid of __instance_registry and rely solely on the > restricted access to __instance_counter and the fact that it is > monotonically increasing to generate IDs. I wrote the second, simpler > version of __gen_id to that end, but it doesn't work! No doubt I'm > overlooking something very simple here but I'm not seeing it. > > Any help appreciated. > > > class GameObject: > > # __instance_registry = {"":None} > __instance_counter = 0 > > def __init__(self, name): > self.__name = str(name) > self.__id = self.__gen_id() > > # def __gen_id(self): > # ty = self.__class__.__name__ > # id = '' > # while id in self.__instance_registry: > # id = '%s_%d' % (ty, self.__instance_counter) > # self.__instance_counter += 1 # > self.__instance_registry[id] = self # return id > > def __gen_id(self): > ty = self.__class__.__name__ > id = '%s_%d' % (ty, self.__instance_counter) > self.__instance_counter += 1 return id > > def __str__(self): > return "name = '%s' id = '%s'" % (self.__name, self.__id) > > > go1 = GameObject("GO1") > go2 = GameObject("GO2") > go3 = GameObject("GO3") > print(go1) > print(go2) > print(go3) > > > # Results with original __gen_id method # name = 'GO1' id = > 'GameObject_0' > # name = 'GO2' id = 'GameObject_1' > # name = 'GO3' id = 'GameObject_2' > > > # Results with new simpler __gen_id method, __instance_counter not being > incremented # name = 'GO1' id = 'GameObject_0' > # name = 'GO2' id = 'GameObject_0' > # name = 'GO3' id = 'GameObject_0' why reinvent the wheel? why not simply use pythons builtin id function? each new instance of an object is automatically assigned a unique ID -- I'm a soldier, not a diplomat. I can only tell the truth. -- Kirk, "Errand of Mercy", stardate 3198.9 -- https://mail.python.org/mailman/listinfo/python-list
Re: Question re class variable
Op 29-09-15 om 11:27 schreef ple...@gmail.com: > I have a perplexing problem with Python 3 class variables. I wish to generate > an unique ID each time an instance of GameClass is created. There are two > versions of the __gen_id method with test run results for each listed below > the code. The problem is that in python you can't change a class variable through an instance. The moment you try, you create an instance attribute. > class GameObject: > > # __instance_registry = {"":None} > __instance_counter = 0 > > def __init__(self, name): > self.__name = str(name) > self.__id = self.__gen_id() > > def __gen_id(self): > ty = self.__class__.__name__ > id = '%s_%d' % (ty, self.__instance_counter) > self.__instance_counter += 1 This last line doesn't work as expected. What happens is equivallent to the following. self.__instance_counter = self.__instance_counter + 1 But the self.__instance_counter are two different things here. On the right hand python finds that self has no __instance_counter attribute so it will fetch the value from the class. However on the left hand, python will create an attribute for self and assign the value to it. Python will not rebind the class variable. -- Antoon Pardon -- https://mail.python.org/mailman/listinfo/python-list
Re: Question re class variable
On 09/29/2015 01:02 PM, jmp wrote: class GameObject: @property def id(self): return id(self) #use the builtin id function print GameObject().id Cheers, JM I should add that until you don't serialize your object you're fine. If you need to serialize it, you may want to look at https://docs.python.org/3/library/uuid.html import uuid class GameObject: def __init__(self): self._id = None @property def id(self): if self._id is None: # make a UUID based on the host ID and current time self._id = uuid.uuid1() return self._id -- https://mail.python.org/mailman/listinfo/python-list
Re: Question re class variable
On Tue, 29 Sep 2015 09:17 pm, Anssi Saari wrote: [...] >> The problem is that in python you can't change a class variable through >> an instance. The moment you try, you create an instance attribute. > > That much is clear but why does his other version of __gen_id() work > (after a fashion)? It doesn't increment the class variable but the > instances get an incremental id. > > The function was like this: > > def __gen_id(self): > ty = self.__class__.__name__ > id = '' > while id in self.__instance_registry: > id = '%s_%d' % (ty, self.__instance_counter) > self.__instance_counter += 1 > self.__instance_registry[id] = self > return id This works because it doesn't assign to self.__instance_registry itself, it assigns to an item within the existing self.__instance_registry. So the registry object (a dict?) gets modified in place, not re-bound or shadowed by an instance attribute of the same name. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: Question re class variable
Antoon Pardonwrites: > Op 29-09-15 om 11:27 schreef ple...@gmail.com: >> I have a perplexing problem with Python 3 class variables. I wish to >> generate an unique ID each time an instance of GameClass is >> created. There are two versions of the __gen_id method with test run >> results for each listed below the code. > > The problem is that in python you can't change a class variable through an > instance. The moment you > try, you create an instance attribute. That much is clear but why does his other version of __gen_id() work (after a fashion)? It doesn't increment the class variable but the instances get an incremental id. The function was like this: def __gen_id(self): ty = self.__class__.__name__ id = '' while id in self.__instance_registry: id = '%s_%d' % (ty, self.__instance_counter) self.__instance_counter += 1 self.__instance_registry[id] = self return id Also, is there any problem with incrementing GameObject.__instance_counter from __gen_id()? I guess not? -- https://mail.python.org/mailman/listinfo/python-list
Re: Question re class variable
On 09/29/2015 11:27 AM, ple...@gmail.com wrote: I have a perplexing problem with Python 3 class variables. Your problem is that when assigning values to your class attribute, you are actually creating a instance attribute. class Foo: bar = "I'm a class attribute" def __init__(self): self.bar = "I'm an instance attribute" def foo(self): print self.bar print Foo.bar # this is how you set a class attribute from an instance Foo.bar = "I am still a class attribute" print Foo.bar Foo.foo() I'm an instance attribute I'm a class attribute I am still a class attribute What can be confusing is that assuming you never use the same name for a class an instance attribute (that would be bad code), you can access your class attribute from the instance: class Foo: bar = "I'm a class attribute" def foo(self): # python will look into the class scope if not found in the instance print self.bar # this is not an assignment so we're fine Foo.foo() I'm an class attribute As side note and unrelated topic, your are using name mangling (attribute starting with __), are you sure you need it ? You need a strong motive to use this feature otherwise you're making things difficult for yourself without any benefit. Finally here's how I'd code your id, to give some idea on alternative ways: class GameObject: @property def id(self): return id(self) #use the builtin id function print GameObject().id Cheers, JM -- https://mail.python.org/mailman/listinfo/python-list
Re: Question re class variable
Op 29-09-15 om 13:17 schreef Anssi Saari: > Antoon Pardonwrites: > >> Op 29-09-15 om 11:27 schreef ple...@gmail.com: >>> I have a perplexing problem with Python 3 class variables. I wish to >>> generate an unique ID each time an instance of GameClass is >>> created. There are two versions of the __gen_id method with test run >>> results for each listed below the code. >> The problem is that in python you can't change a class variable through an >> instance. The moment you >> try, you create an instance attribute. > That much is clear but why does his other version of __gen_id() work > (after a fashion)? It doesn't increment the class variable but the > instances get an incremental id. > > The function was like this: > > def __gen_id(self): > ty = self.__class__.__name__ > id = '' > while id in self.__instance_registry: > id = '%s_%d' % (ty, self.__instance_counter) > self.__instance_counter += 1 > self.__instance_registry[id] = self > return id Because you check against the class variable __instance_registry. That variable isn't rebound, it is mutated, so it remains a class variable and can thus be used to check which id's are already in use. So you increment your counter until the corresponding id is not in the __instance_registry. -- Antoon Pardon. -- https://mail.python.org/mailman/listinfo/python-list
Re: Question re class variable
Inalister writes: > why not simply use pythons builtin id function? > each new instance of an object is automatically assigned a unique ID It's only guaranteed to be unique for objects that exist at the same time. If an object is created and destroyed and then another new object is created, the ID of those two objects can be the same. -- John Gordon A is for Amy, who fell down the stairs gor...@panix.com B is for Basil, assaulted by bears -- Edward Gorey, "The Gashlycrumb Tinies" -- https://mail.python.org/mailman/listinfo/python-list