13 Replies - 559 Views - Last Post: 06 February 2013 - 06:24 AM Rate Topic: -----

#1 Asleep  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 10
  • Joined: 06-February 13

Class Instantiation Increment?

Posted 06 February 2013 - 04:12 AM

I'm new to Python and programming in general. Reading a few tutorials online and learning what I can.
class NewUser:
    uid = 0
    def __init__(self, username):
        self.username = username
        self.uid += 1

x = NewUser("User1")
print(x.username)
print(x.uid)

y = NewUser("User2")
print(y.username)
print(y.uid)



My question is, how do I make uid increment on each instance of NewUser?

Is This A Good Question/Topic? 0
  • +

Replies To: Class Instantiation Increment?

#2 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3252
  • View blog
  • Posts: 10,902
  • Joined: 12-December 12

Re: Class Instantiation Increment?

Posted 06 February 2013 - 04:30 AM

class NewUser:
    uid = 0
    def __init__(self, username):
        self.username = username
        NewUser.uid += 1

x = NewUser("User1")
print(x.username)
print(x.uid)

y = NewUser("User2")
print(y.username)
print(y.uid)

As soon as you use self.uid Python copies the value of the shared uid to an instance variable (field). To use the shared value you need to refer to it as a static member of the Class.

Personally, although I am a fan of Python, I find this behaviour slightly odd and confusing.

It is also annoying that, although we don't have to declare variables, we do have to (somehow!) assign them a value before referencing them.

This post has been edited by andrewsw: 06 February 2013 - 04:38 AM

Was This Post Helpful? 0
  • +
  • -

#3 Asleep  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 10
  • Joined: 06-February 13

Re: Class Instantiation Increment?

Posted 06 February 2013 - 04:42 AM

Thanks for your response. Not sure if I understood that correctly,
what I did understand that the issue was the use of self because it create a copy of the data rather than the data itself.

class NewUser:
    uid = 0
    def __init__(self, username):
        self.username = username
        NewUser.uid += 1

x = NewUser("User1")
print(x.username)
print(x.uid)

y = NewUser("User2")
print(y.username)
print(y.uid)

z = NewUser("User3")
print(z.username)
print(z.uid)

print("Test Case")
print("UID Y is")
print(y.uid)


This is my new code. y seems to have changed its value to 3 permanently though. How would I have them all keep their own original values?
Was This Post Helpful? 0
  • +
  • -

#4 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2091
  • View blog
  • Posts: 3,185
  • Joined: 21-June 11

Re: Class Instantiation Increment?

Posted 06 February 2013 - 04:51 AM

View Postandrewsw, on 06 February 2013 - 12:30 PM, said:

class NewUser:
    uid = 0
    def __init__(self, username):
        self.username = username
        NewUser.uid += 1



That won't work because:

View PostAsleep, on 06 February 2013 - 12:42 PM, said:

y seems to have changed its value to 3 permanently though. How would I have them all keep their own original values?


After incrementing NewUser.uid, you have to assign a copy of it to self.uid, so the object's uid doesn't change when the class's uid changes the next time:

class NewUser:
    uid = 0
    def __init__(self, username):
        self.username = username
        NewUser.uid += 1
        self.uid = NewUser.uid



View Postandrewsw, on 06 February 2013 - 12:30 PM, said:

As soon as you use self.uid Python copies the value of the shared uid to an instance variable (field).


That's not true actually. If the variable has never been set for an object, the_object.the_variable will always refer to TheClass.the_variable - not just the first time it's accessed. You have to explicitly write the_object.the_variable = TheClass.the_variable to get an independent copy.
Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5780
  • View blog
  • Posts: 12,596
  • Joined: 16-October 07

Re: Class Instantiation Increment?

Posted 06 February 2013 - 04:55 AM

@andrewsw: you need a self, you're just messing with the class variable, which doesn't make sense

You probably want something like:
class User: # new seems redundant
	__NEXT_UID = 1 # note the underscore, tell other classes to ignore this
	def __init__(self, username):
		self.username = username
		self.uid = User.__NEXT_UID # asign the next id
		User.__NEXT_UID += 1 # increment

	def __str__(self): # for bonus points, let's implement to string
		return "{0} {1}".format(self.uid, self.username)



Results:
>>> users = [ User('Alice'), User('Bob'), User('Chuck') ]
>>> for user in users:
...     print(user)
... 
1 Alice
2 Bob
3 Chuck
>>> dir(User)
['_User__NEXT_UID', '__doc__', '__init__', '__module__', '__str__']
>>> dir(users[0])
['_User__NEXT_UID', '__doc__', '__init__', '__module__', '__str__', 'uid', 'username']
>>> 



See how instances have the self properties?

Note how user NEXT_UID is slightly munged up? Compare to:
>>> class Foo:
...     bar = 1
... 
>>> dir(Foo)
['__doc__', '__module__', 'bar']
>>> 



In Python, nothing is truly private. However, you can mark things you don't want other classes to mess with.

Hope this helps.
Was This Post Helpful? 1
  • +
  • -

#6 Asleep  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 10
  • Joined: 06-February 13

Re: Class Instantiation Increment?

Posted 06 February 2013 - 04:59 AM

Thank you, I was trying to think of how to do that but my attempts were futile.

I'm slightly confused as to the why exactly but, I'm guessing that its because of how Python does variables? Would you be able to explain why its a pointer instead of a new variable so I can not get confused in the future?

What I understand,
classname.variable is a pointer
Setting x to a new instance (or I assumed it was a new instance) of classname.variable only sets a pointer to the data and not an assignment to a new variable.

Why does using self work in this case then? How is it that self isn't just a pointer?
Was This Post Helpful? 0
  • +
  • -

#7 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3252
  • View blog
  • Posts: 10,902
  • Joined: 12-December 12

Re: Class Instantiation Increment?

Posted 06 February 2013 - 05:11 AM

sepp2k

Quote

That's not true actually. If the variable has never been set for an object, the_object.the_variable will always refer to TheClass.the_variable - not just the first time it's accessed. You have to explicitly write the_object.the_variable = TheClass.the_variable to get an independent copy.

Yes, I should have said "as soon as we assign to self.uid..".

[It's easy to wake people up at DIC - just make a slight mis-statement :) ]

baavgai

Quote

you need a self, you're just messing with the class variable, which doesn't make sense

Why doesn't it make sense? That's what the OP asked for:

Quote

My question is, how do I make uid increment on each instance of NewUser?

This post has been edited by andrewsw: 06 February 2013 - 05:14 AM

Was This Post Helpful? 0
  • +
  • -

#8 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3252
  • View blog
  • Posts: 10,902
  • Joined: 12-December 12

Re: Class Instantiation Increment?

Posted 06 February 2013 - 05:22 AM

@baavgai
.. but, yes, the name mangling does offer the illusion of privacy for the class variable.
Was This Post Helpful? 0
  • +
  • -

#9 Asleep  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 10
  • Joined: 06-February 13

Re: Class Instantiation Increment?

Posted 06 February 2013 - 05:39 AM

Took me some time and some googling but I believe I understand your solution now baagvai, thanks for sharing. Thank you as well to everyone else for their assistance.
class NewUser:
    #"__" denotes a special method that classes do not modify.
    #We set our User Id here
    __USER_ID = 0

    #This is a function. "__init__" is the
    #predefined function to run when instanciated
    #self is always supplied, so the call needs to be
    #classname(variable) in this case, NewUser("Username")
    def __init__(self, username):
        #This sets NewUser.username to our variable from instanciation
        self.username = username

        #This sets the instanced NewUser UID to the amount originally set
        self.uid = NewUser.__USER_ID

        #This incriments our base User Id for the next time called.
        NewUser.__USER_ID += 1

    #"__str__" is the predefined function for strings.
    #It determines the output when a class is explicitly asked
    #for a string output
    def __str__(self):
        #format() is a special method for strings that replace
        #certain formats of data in a string; in this case positional data
        #{0} represents the first data given
        #{1} represents the second data given
        return("User ID:{0}, Username:{1}").format(self.uid, self.username)

x = NewUser("Username 1")
y = NewUser("Username 2")

print(x)
print(y)



This is my final solution; Please look over my comments to ensure my understanding of what the specific parts you added in are correct.

My only confusions lay within the "self" and the "__" before the variable names. I am sure some googling will relieve me of those shortly.
Was This Post Helpful? 0
  • +
  • -

#10 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3252
  • View blog
  • Posts: 10,902
  • Joined: 12-December 12

Re: Class Instantiation Increment?

Posted 06 February 2013 - 05:50 AM

The double-underscores at the front create name-mangling. It is an attempt to create private (hidden) variables (Python doesn't implement the idea of privacy as other languages do).

If you were to attempt
print(NewUser.__NEXT_UID)

(outside of the Class) you would receive an error:

Quote

AttributeError: type object 'NewUser' has no attribute '__NEXT_UID'

but you can still access it using:
print(NewUser._NewUser__NEXT_UID)

so it is not truly private. But this last line of code should never be used, as it would defeat the whole purpose!

The idea is that because we, as programmers, have used name-mangling to confirm that "this should be private" other programmers should not be tempted to muck around.

This post has been edited by andrewsw: 06 February 2013 - 05:53 AM

Was This Post Helpful? 0
  • +
  • -

#11 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5780
  • View blog
  • Posts: 12,596
  • Joined: 16-October 07

Re: Class Instantiation Increment?

Posted 06 February 2013 - 05:59 AM

Glad you're playing with it.

The self is a reference to, well, the object itself. Most languages have an internal reference to this type of variable, but python wants you to pass it every time. Remember that each instance of a class is a distinct object and you need some way to figure out the state of that object in your methods. Hence, self.

The underscores are just convention for access levels, bolstered by a little name mangling. It's more documentation than anything else, telling users of your class that it's for internal use and not to mess with it.

View Postandrewsw, on 06 February 2013 - 07:11 AM, said:

baavgai

Quote

you need a self, you're just messing with the class variable, which doesn't make sense

Why doesn't it make sense? That's what the OP asked for:

Quote

My question is, how do I make uid increment on each instance of NewUser?


Do you really think they wanted a value that's attached to the class, not the object? Even if you read it as such, that's clearly not the intent.

Does this make sense:
>>> class NewUser:
...     uid = 0
...     def __init__(self, username):
...             self.username = username
...             NewUser.uid += 1
... 
>>> 
>>> for x in [ NewUser("User1"), NewUser("User2") ]:
...     print(x.username)
...     print(x.uid)
... 
User1
2
User2
2
>>> 


Was This Post Helpful? 0
  • +
  • -

#12 Asleep  Icon User is offline

  • New D.I.C Head

Reputation: 4
  • View blog
  • Posts: 10
  • Joined: 06-February 13

Re: Class Instantiation Increment?

Posted 06 February 2013 - 06:02 AM

I see! Thank you very much then andrewsw! All the technical jargon on most sites I've been reading go over my head!
Was This Post Helpful? 0
  • +
  • -

#13 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3252
  • View blog
  • Posts: 10,902
  • Joined: 12-December 12

Re: Class Instantiation Increment?

Posted 06 February 2013 - 06:07 AM

@Asleep
Yes, your understanding seems good from your code-comments. But I would avoid the use of the term pointer. While it may be, technically, accurate, in Python we talk about Dictionaries. Most everything (even primitives to an extent, I understand) can be regarded as dictionaries.

Classes are dictionaries and they have attributes, which are also referred to as Class-members.

@baavgai

Quote

Do you really think they wanted a value that's attached to the class, not the object? Even if you read it as such, that's clearly not the intent.

Yes, I was a bit too literal in the interpretation of the question.

@Asleep
And they are spelt instantiation and increment :). I know.. it's confusing, as we refer to an instance not an instant?!
Was This Post Helpful? 0
  • +
  • -

#14 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5780
  • View blog
  • Posts: 12,596
  • Joined: 16-October 07

Re: Class Instantiation Increment?

Posted 06 February 2013 - 06:24 AM

OOP ( Object Oriented Programming ) proliferates jargon. Computers, in general, love their TLAs (Three Letter Acronyms). ;)

Start here: http://en.wikipedia....mputer_science)

It might be a little much, but it will give you something to go on.

Python, in particular, has a lot to say about objects, often claiming to be nothing but. This looked pretty good: http://www.voidspace...icles/OOP.shtml

Don't worry, it will all make sense eventually. The more you program, the more context you'll have for this stuff to fit into.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1