Re: Question re class variable

2015-09-29 Thread alister
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

2015-09-29 Thread Antoon Pardon
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

2015-09-29 Thread jmp

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

2015-09-29 Thread Steven D'Aprano
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

2015-09-29 Thread Anssi Saari
Antoon Pardon  writes:

> 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

2015-09-29 Thread jmp

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

2015-09-29 Thread Antoon Pardon
Op 29-09-15 om 13:17 schreef Anssi Saari:
> Antoon Pardon  writes:
>
>> 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

2015-09-29 Thread John Gordon
In  alister 
 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