Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
agscala
Jul 12, 2008

Quick stupid question for a beginner:
If I made some project (lets say... some roguelike game) in python, would I need to have python installed on every machine to play it? Is there a way to avoid that?

Adbot
ADBOT LOVES YOU

lilbean
Oct 2, 2003

agscala posted:

Quick stupid question for a beginner:
If I made some project (lets say... some roguelike game) in python, would I need to have python installed on every machine to play it? Is there a way to avoid that?
You can use py2exe (http://www.py2exe.org/) to make a self-contained executable for Windows platforms.

Lurchington
Jan 2, 2003

Forums Dragoon
I'm in the middle of my personal coding project of the moment (http://code.google.com/p/keasby/ *)

and I'm looking into a good way of doing data persistence. Currently I'm using shelve to cache away what are essentially pickled XML blocks that have been parsed through xml.dom.minidom.

I'm also using anydbm to keep a dict of past search results.

What are the best tools out there to do the job?


* the version that's currently there is basically avoiding Object Oriented / Best Practices because I was copying the logic of a perl script.

The svn code I'm more proud of, although it needs to be tightened, a lot.

Thots and Prayers
Jul 13, 2006

A is the for the atrocious abominated acts that YOu committed. A is also for ass-i-nine, eight, seven, and six.

B, b, b - b is for your belligerent, bitchy, bottomless state of affairs, but why?

C is for the cantankerous condition of our character, you have no cut-out.
Grimey Drawer

lilbean posted:

You can use py2exe (http://www.py2exe.org/) to make a self-contained executable for Windows platforms.

...and Python is standard on Linux/BSD and OSX. So you'd be good to go.

SlightlyMadman
Jan 14, 2005

lilbean posted:

You can use py2exe (http://www.py2exe.org/) to make a self-contained executable for Windows platforms.

If pygame or pyglet was used, would they need to be installed as well, or would the exe contain everything needed?

lilbean
Oct 2, 2003

SlightlyMadman posted:

If pygame or pyglet was used, would they need to be installed as well, or would the exe contain everything needed?
It bundles all the dependencies (at least when I tried it with Pygame it did).

SlightlyMadman
Jan 14, 2005

So I'm having an interesting time with python so far (the only time I'd used it before was map scripts for CIV, which are pretty simple), but I've run into an interesting issue. I have a game that runs perfectly on my WinXP laptop, but absolutely abysmally on my Ubuntu laptop. The thing is, they're both almost the same model (WinXP is Thinkpad R60, Ubuntu is Thinkpad T60, which is actually better).

If I comment out all the main loop of blit code, it runs fine. Here's the code in question:

code:
for xx in range(len(self.board)):
	for yy in range(len(self.board[xx])):
		#get a raw location
		draw_x = self.tile_width * xx - offset_x
		draw_y = self.tile_height * yy - offset_y
				
		if draw_x < self.view_width and draw_y < self.view_height and draw_x >= 0 and draw_y >= 0:
			if self.board[xx][yy] == 0:
				self.floor.blit(draw_x, draw_y)
			elif self.board[xx][yy] == 1:
				self.wall.blit(draw_x, draw_y)
The view port (view_width and view_height) is 480x480, and the tiles are 32x32, so that's like less than 200 draws. Am I missing some important aspect of linux graphics display that's not an issue on windows?

ATLbeer
Sep 26, 2004
Über nerd
Has anyone had a good experience with a messaging package?

I have used the XMLRPC library and I LOVE it.. I really want to use the library but, I would like some sort of central logging of all messages that have gone through the system for debugging and error checking since it's going to be transactional system. I guess I could funnel all the XMLRPC requests through a handler which would log the message and pass it along to the appropriate system but, that seems like a cheap hack and a bottle neck.

A Jabber server seems like the only solution but, I can't seem to bring my self to be a fan of the libraries out there. They all seem to be a bit too "un-pythonic" and obtuse.

Anyone have any experience in a client-server-client messaging system for Python that you've liked to work with or do you believe I'm just stuck hacking up a Pythonic wrapper for an existing Jabber wrapper?

tef
May 30, 2004

-> some l-system crap ->

ATLbeer posted:

I would like some sort of central logging of all messages that have gone through the system for debugging and error checking since it's going to be transactional system.

Does the logging module not do what you want?

http://docs.python.org/lib/module-logging.html

Specifically the syslog module, or the httplog module:
http://docs.python.org/lib/node416.html
http://docs.python.org/lib/node420.html

duck monster
Dec 15, 2004

ATLbeer posted:

Has anyone had a good experience with a messaging package?

I have used the XMLRPC library and I LOVE it.. I really want to use the library but, I would like some sort of central logging of all messages that have gone through the system for debugging and error checking since it's going to be transactional system. I guess I could funnel all the XMLRPC requests through a handler which would log the message and pass it along to the appropriate system but, that seems like a cheap hack and a bottle neck.

A Jabber server seems like the only solution but, I can't seem to bring my self to be a fan of the libraries out there. They all seem to be a bit too "un-pythonic" and obtuse.

Anyone have any experience in a client-server-client messaging system for Python that you've liked to work with or do you believe I'm just stuck hacking up a Pythonic wrapper for an existing Jabber wrapper?

The XML-RPC library is astonishingly effective and simple to use.

poo poo. Its a shame you didn't ask this 6-7 months ago, I wrote an awesome system that did precisely this. Central logging system with a web interface, switchable logging levels, all sorts of statistics, and a big bag of interfaces to talk to it in various languages. (PHP, Python, Perl, C). The boss let me LGPL it all, but when I quit the job I never took a copy of the code, and I did my usual and burnt the bridge with a flamethrower, so I probably can't get it for you.

But heres how it basically worked;- Make a simple daemon (just descend from Simple xml server class) that takes messages, and poo poo them into a database. Get out Django, or poo poo even PHP if you wish, an punk out a little web interface to it. An then just make a little includable library to catch errors and fwd them across to the daemon.

SlightlyMadman
Jan 14, 2005

If anyone else is having trouble with pyglet, a word of warning. Apparently it's just not optimized for 2d sprite games at this point. Apparently it's coming though. There's some good information about my exact problem above, here:

http://groups.google.com/group/pyglet-users/browse_thread/thread/607b94cdcc8254ec

Thankfully I only put a few hours into the game so far (pyglet is definitely easy to get started), so I don't mind starting over again with pygame instead.

Scaevolus
Apr 16, 2007

SlightlyMadman posted:

So I'm having an interesting time with python so far (the only time I'd used it before was map scripts for CIV, which are pretty simple), but I've run into an interesting issue. I have a game that runs perfectly on my WinXP laptop, but absolutely abysmally on my Ubuntu laptop. The thing is, they're both almost the same model (WinXP is Thinkpad R60, Ubuntu is Thinkpad T60, which is actually better).

If I comment out all the main loop of blit code, it runs fine. Here's the code in question:

code:
for xx in xrange(len(self.board)):
	for yy in range(len(self.board[xx])):
		#get a raw location
		draw_x = self.tile_width * xx - offset_x
		draw_y = self.tile_height * yy - offset_y
				
		if draw_x < self.view_width and draw_y < self.view_height and draw_x >= 0 and draw_y >= 0:
			if self.board[xx][yy] == 0:
				self.floor.blit(draw_x, draw_y)
			elif self.board[xx][yy] == 1:
				self.wall.blit(draw_x, draw_y)
The view port (view_width and view_height) is 480x480, and the tiles are 32x32, so that's like less than 200 draws. Am I missing some important aspect of linux graphics display that's not an issue on windows?
Well, you can simplify that code to

code:
for xx in xrange(len(self.board)):
	for yy in xrange(len(self.board[xx])):
		#get a raw location
		draw_x = self.tile_width * xx - offset_x
		draw_y = self.tile_height * yy - offset_y
				
		if 0 <= draw_x < self.view_width and 0 <= draw_y < self.view_height:
			if self.board[xx][yy]:
				self.wall.blit(draw_x, draw_y)
			else:
				self.floor.blit(draw_x, draw_y)
In particular, your use of range(), which returns a list, instead of xrange(), which returns an iterator, could drastically reduce performance. Also, you can do "0 <= foo < 100", which is handy for stuff like this.

Consider iterating over the 480x480 viewport instead of over every pixel and seeing it should be drawn-- that should improve performance as well.

Scaevolus fucked around with this message at 03:34 on Aug 1, 2008

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

Scaevolus posted:

0 <= draw_x < self.view_width

Holy poo poo!

SlightlyMadman
Jan 14, 2005

Scaevolus posted:

In particular, your use of range(), which returns a list, instead of xrange(), which returns an iterator, could drastically reduce performance. Also, you can do "0 <= foo < 100", which is handy for stuff like this.

Consider iterating over the 480x480 viewport instead of over every pixel and seeing it should be drawn-- that should improve performance as well.

Thanks! I definitely appreciate the optimizations, and I'll try it out. I didn't even really consider it though, because there's only 24 elements in each direction, so that's just 576 iterations. There's no excuse for that to take the 5-10 seconds it's taking now, so it's definitely the blit code.

edit: yeah, just tried it. No noticeable difference. Good to know about xrange, though.

SlightlyMadman fucked around with this message at 16:08 on Aug 1, 2008

zero knowledge
Apr 27, 2008
I've run into some strange behavior from some class members in my Python program.

code:
class Square:
    def __init__ (self, _label, _face, _indexR, _indexC, _conflicts = []):
        self.label = _label
        self.face = _face
        self.indexR = _indexR
        self.indexC = _indexC
        #conflicts is a list of Conflict objects
        self.conflicts = _conflicts
    
    def addConflict(self, sqr, type):
        """Adds a labeling conflict to the square's list"""
        #sqr is a square object, type is just a string
        self.conflicts.append(Conflict(sqr, type))

class Conflict:
    def __init__(self, _otherSquare, _type):
        self.otherSquare = _otherSquare
        self.type = _type
So each Square (of which there are 96 on a cube) has a member which is a list of Conflict objects, which I initialize to be empty. The problem is that when I call addConflict on a given Square, it adds a Conflict object to every Square's conflicts member. Essentially, conflicts is behaving like a static class member.

This baffles me because if I wanted it to be static, then I would have had to use Square.conflicts in the __init__ and addConflict functions and not use self parameters in those functions.

Google is giving me nothing but instructions on how to make things static rather than explanations of why this is behaving statically out of nowhere. Anyone have a hint on what's going on here?

Allie
Jan 17, 2004

Default arguments are initialized only once. Every time you call Square.__init__() it adds to the list in the _conflicts parameter. Set its default value to None and instantiate it inside the function:

code:
def foo(stuff=None):
    if stuff is None:
        stuff = []
You should generally only use immutable types for default values.

zero knowledge
Apr 27, 2008

Milde posted:

Default arguments are initialized only once. Every time you call Square.__init__() it adds to the list in the _conflicts parameter. Set its default value to None and instantiate it inside the function:

Ah, that makes a lot of sense. Thanks a lot!

SlightlyMadman
Jan 14, 2005

SlightlyMadman posted:

Thanks! I definitely appreciate the optimizations, and I'll try it out. I didn't even really consider it though, because there's only 24 elements in each direction, so that's just 576 iterations. There's no excuse for that to take the 5-10 seconds it's taking now, so it's definitely the blit code.

edit: yeah, just tried it. No noticeable difference. Good to know about xrange, though.

Just in case anyone's curious, I just rewrote my game in straight pygame, and it performs beautifully. I even tried running it on my N800 tablet, and it runs with only a slight lag, which I'm sure further optimization could take care of.

agscala
Jul 12, 2008

I want to start making a roguelike game in python, and I was going to use the curses module to do all of my console interaction. I ran into a snag right off the bat. First off, curses isn't available on windows, so I'm using wcurses. Whenever I try to import curses, I get:
code:
Python 2.5.2 (r252:60911, Feb 21 2008, 13:11:45) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import curses
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python25\lib\curses\__init__.py", line 15, in <module>
    from _curses import *
ImportError: No module named _curses
I looked all over the web and I couldn't find a solution. I emailed the creator of wcurses and haven't received a response... Any help is much appreciated for this beginner!

SlightlyMadman
Jan 14, 2005

agscala posted:

I want to start making a roguelike game in python, and I was going to use the curses module to do all of my console interaction.

I'm really liking pygame for simple 2D graphics, and there's many great roguelike tile sets available. Or if you prefer text, you can just use images of text for your tiles. Not much harder to code up front, and gives you a lot more flexibility in the end.

Bozart
Oct 28, 2006

Give me the finger.

SlightlyMadman posted:

I'm really liking pygame for simple 2D graphics, and there's many great roguelike tile sets available. Or if you prefer text, you can just use images of text for your tiles. Not much harder to code up front, and gives you a lot more flexibility in the end.

then you can make a game where you manage a bunch of goblins that live in a cave...

tef
May 30, 2004

-> some l-system crap ->

agscala posted:

I looked all over the web and I couldn't find a solution. I emailed the creator of wcurses and haven't received a response... Any help is much appreciated for this beginner!

Extract the curses files into c:\python25\lib not c:\python25\lib\site-packages

agscala
Jul 12, 2008

tef posted:

Extract the curses files into c:\python25\lib not c:\python25\lib\site-packages
Thanks, that was the correct solution.

I want to give pygame a shot, I'm not happy about how it won't run on v2.5, though.

SlightlyMadman
Jan 14, 2005

I am current in complete and total awe of python and pygame. Rather than deal with getting all my classes and data structures perfect, I decided I just wanted to make a game that I could interact with by the end of the day. It's not exactly fun yet, but I've got most of the game implemented to some degree: pathfinding, mini-map, combat routines, line of site with fog of war. All told, I've probably put 5-6 hours of actual coding time into this:



I've gotten projects further than this in the past, but never this quickly. Hopefully it doesn't fall apart at the seams later on because of it.

Xenos
Jun 17, 2005

agscala posted:

Thanks, that was the correct solution.

I want to give pygame a shot, I'm not happy about how it won't run on v2.5, though.

According the pygame site, 1.8.1 runs on python 2.4, 2.5, and 2.6, but they suggest not running 2.6 if you want compatibility with older versions of Windows. Do these not work? I've never used pygame before, but I've been thinking about maybe starting a project in it, and it would be good to know if something's up with compatibility.

aeiou
Jul 12, 2006

It's cold in here...
Just kidding! It's to
fool enemies..

SlightlyMadman posted:

If anyone else is having trouble with pyglet, a word of warning. Apparently it's just not optimized for 2d sprite games at this point. Apparently it's coming though. There's some good information about my exact problem above, here:

http://groups.google.com/group/pyglet-users/browse_thread/thread/607b94cdcc8254ec

Thankfully I only put a few hours into the game so far (pyglet is definitely easy to get started), so I don't mind starting over again with pygame instead.

Version 1.1 of Pyglet was just released yesterday. Here is a quote from the announcement...

pyglet.org posted:

pyglet 1.1 is backward compatible with pyglet 1.0 and introduces many new features such as formatted text rendering, animated GIF support, fast sprite rendering, resource loading and a managed event loop.

I haven't had much time to play around with it myself yet, but it looks really spiffy. I'm interested in hearing if anyone else has used pyglet.

SlightlyMadman
Jan 14, 2005

Can anyone help me with using pickle to serialize and deserialize complex objects? I want to be able to do something like this:

code:
def __getstate__(self):
  self.image = None
  return self

def __setstate__(self, state):
  self = state
  self.image = self.LoadImage()
The purpose is to remove and recreate the image reference, because it's not serializable. The problem is that the "return self" line in __getstate__ causes only the basic object to be serialized, but none of the members. If I instead say "return (self.foo, self.bar, self.baz, self.bat)" and then parse them back out in __setstate__ it works fine, but every inherited member then needs their own custom __getstate__ and __setstate__ methods, which have to also include all the base class' members. This violates every rule of OOP I know, so I'm sure there's got to be a better way.

I think I have to do something with the __dict__ member, but I can't quite figure it out. Google keeps coming up with seemingly helpful examples, but they end up being far too simplistic and don't solve the inherited class issue.

I can post the full code if anyone thinks they can help.

Update: If anyone is curious, this is the code I ended up needing:
code:
	def __getstate__(self):
		self.NukeImages()
		return self.__dict__
	
	def __setstate__(self, state):
		self.__dict__.update(state)
		self.LoadImages()
I knew it was something simple!

SlightlyMadman fucked around with this message at 16:57 on Aug 13, 2008

ahobday
Apr 19, 2007

I want to learn Python by making a simple address/phone book application.

In terms of the data structure, is it possible to define an entry in the phone book as a class, and then simply store those entries (Of class Entry, for example) in a list? Would that allow me to add/delete the entries and whatnot?

bitprophet
Jul 22, 2004
Taco Defender

Centipeed posted:

I want to learn Python by making a simple address/phone book application.

In terms of the data structure, is it possible to define an entry in the phone book as a class, and then simply store those entries (Of class Entry, for example) in a list? Would that allow me to add/delete the entries and whatnot?

Depends on what sort of persistence you want. If you're talking about a trying-stuff-out demo app where you don't actually care about the data sticking around, then sure -- lists can hold any object, and class instances are of course objects like anything else. However, once your program stops running, your list will obviously disappear.

If you wanted to keep the data on disk somewhere, the typical method is to use a SQL database, the simplest such being SQLite (which stores stuff in simple files, as opposed to the heavyweights which are full blown servers) -- Python 2.5 has a built-in SQLite library so all you'd need is to install the SQLite binaries and you're all set.

Edit: Fix retarded typo.

bitprophet fucked around with this message at 00:27 on Aug 14, 2008

ahobday
Apr 19, 2007

For this exercise, can't I just store the list in a text file with simple markup? A database seems like overkill, even it is is only SQLite.

bitprophet
Jul 22, 2004
Taco Defender

Centipeed posted:

For this exercise, can't I just store the list in a text file with simple markup? A database seems like overkill, even it is is only SQLite.

What do you mean by "simple markup"? I suppose you could use "<whatever> separate values" (comma, tab, pipe, whatever) but then you need to translate back and forth every time you save.

And, yea, SQL is a bit of overkill; I did say "the typical method", not "the only method" ;) I think the best middle-of-the-road approach would be to use the pickle module, which lets you store Python objects in strings (and thus in files).

I probably should have mentioned that first, honestly, but I'm too used to thinking of "real" applications, for which stuff like pickle is almost never a good idea (unless your data sets are very small AND you really want to work with Python objects instead of SQL or an ORM).

agscala
Jul 12, 2008

Centipeed posted:

For this exercise, can't I just store the list in a text file with simple markup? A database seems like overkill, even it is is only SQLite.
Yeah, you don't need SQL for something like that.
Go here: http://docs.python.org/tut/node9.html
and scroll down to section 7.2; it should have everything you need.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...
A question about PDF libraries for Python: ReportLab allows you to *make* PDFs, PyPDF allows you to *edit* them (to the extent of adding and deleting pages), but is there any library that will allow you to interrogate or add to them?

I'm doing some work with PDF ebooks and I'd like to peek at the PDF metadata to rename the files accordingly, and then to merge some annotations (from an iLiad reader) into the main document. However current Python PDF libraries seem to neatly skirt this functionality. I guess what I'm looking for is the Python equivalent of iText. Options?

Oae Ui
Oct 7, 2003

Let's be friends.

aeiou posted:

Version 1.1 of Pyglet was just released yesterday. Here is a quote from the announcement...

I haven't had much time to play around with it myself yet, but it looks really spiffy. I'm interested in hearing if anyone else has used pyglet.

Pyglet has had the fast sprite rendering available through the 1.1 betas for awhile. I've been using it a lot to prototype some things and I've been very happy with performance. If you know what you're doing and use batches in 1.1 it's much faster than Pygame. Even without the 1.1 improvements there was a fast sprite library available called Rabbyt which worked with Pyglet and again would be much faster than Pygame.

I think the problems come from people trying to do things with it exactly like they would in Pygame or other libraries. Pyglet certainly lets you do things that will result in very bad performance (individually blitting each sprite for instance), but I've seen a few demos posted to the Pyglet mailinglist that were very impressive. One generated a few thousand sprites (with transparency) in the form of a particle fountain and ran flawlessly on my old Powerbook G4, and this was done before version 1.1. You simply cannot get anywhere close to that in Pygame.

Pyglet still has a few deficiencies, like no joystick or gamepad support yet, but it seems to be developing much more quickly than Pygame these days. I do however find a lot of things that Pyglet has, like it's event handling, to be much better than what's available for Pygame. Overall I don't think I could ever recommend Pygame over Pyglet to anyone for anything.

By the way, nice name.

Oae Ui fucked around with this message at 19:15 on Aug 14, 2008

SlightlyMadman
Jan 14, 2005

Oae Ui posted:

Pyglet has had the fast sprite rendering available through the 1.1 betas for awhile. I've been using it a lot to prototype some things and I've been very happy with performance. If you know what you're doing and use batches in 1.1 it's much faster than Pygame. Even without the 1.1 improvements there was a fast sprite library available called Rabbyt which worked with Pyglet and again would be much faster than Pygame.

I'm actually having two problems with pygame right now. The first is that there's no way to order a sprite batch, so if I have multiple overlapping sprites in the same batch, I get an annoying flicker where they intersect. The second is that drawing lines directly to the screen seems to be incredibly slow. I've noticed that my game slows down dramatically (drops from about 60fps to 5-10) once I've explored the whole map, because the fog-of-war has been lifted so there's more mini-map to draw.

Would pyglet resolve these issues for me? If so, I might swap back out pygame for it and give it a shot. Thankfully, when I replaced pyglet with pygame initially, I ended up fairly well compartmentalizing the rendering code as a result.

Oae Ui
Oct 7, 2003

Let's be friends.

SlightlyMadman posted:

I'm actually having two problems with pygame right now. The first is that there's no way to order a sprite batch, so if I have multiple overlapping sprites in the same batch, I get an annoying flicker where they intersect. The second is that drawing lines directly to the screen seems to be incredibly slow. I've noticed that my game slows down dramatically (drops from about 60fps to 5-10) once I've explored the whole map, because the fog-of-war has been lifted so there's more mini-map to draw.

Would pyglet resolve these issues for me? If so, I might swap back out pygame for it and give it a shot. Thankfully, when I replaced pyglet with pygame initially, I ended up fairly well compartmentalizing the rendering code as a result.

The way that you do drawing with Pyglet 1.1 is you add sprites to a batch and then call batch.draw(). This renders the whole batch in a single call. To handle ordering sprites can be assigned to ordered groups (you can also do other things here like have setup and teardown code for each group). This sounds like what you're doing but sprites inside of a group will maintain their order so you shouldn't get any flickering.

As for drawing lines, Pyglet still does not have a primitives module, which is one area where it's lacking. However, the new pyglet.graphics API makes drawing shapes in OpenGL a bit easier than it used to be. It's pretty easy to draw a line with it and it will be very fast, especially if added into your main batch. It's pretty easy to wrap into a function.

Adding a line to the batch can be done like this (taking this partly from the pyglet docs):

code:
batch = pyglet.graphics.Batch()
vertex_list = batch.add(2, pyglet.gl.GL_LINES, None,
    ('v2i', (10, 15, 30, 35)),
    ('c3B', (0, 0, 255, 0, 0, 255))
)
You can also just draw it straight to the screen:

code:
pyglet.graphics.draw(2, pyglet.gl.GL_LINES,
    ('v2i', (10, 15, 30, 35)),
    ('c3B', (0, 0, 255, 0, 0, 255))
)
You can draw any other OpenGL primitive like points or poly loops using this.

ahobday
Apr 19, 2007

I finished my phone book application. I have no idea if it was coded well, but it was a decent learning exercise for my first Python program. What I'd like to know, though, is the following:

code:
class Name:
    foo = ""

    def set_variable(self, bar):
        self.foo = bar
I've got limited experience with Java and C++. What I don't get is the "self" in the arguments for the function and before the variable assignment. I'm assuming self refers to the class and not the function in both cases? Why is the class passed to the function as an argument, and why is it used to assign the variable in the class? Surely it should "know" that the variable "foo" is part of the class because the function is inside that class?

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

Centipeed posted:

I finished my phone book application. I have no idea if it was coded well, but it was a decent learning exercise for my first Python program. What I'd like to know, though, is the following:

code:
class Name:
    foo = ""

    def set_variable(self, bar):
        self.foo = bar
I've got limited experience with Java and C++. What I don't get is the "self" in the arguments for the function and before the variable assignment. I'm assuming self refers to the class and not the function in both cases? Why is the class passed to the function as an argument, and why is it used to assign the variable in the class? Surely it should "know" that the variable "foo" is part of the class because the function is inside that class?

Are you familiar with the "static" keyword in C++ and Java? It makes a member variable part of the *class* instead of the *object*. Like this:

code:
class C
{
public:
  int a;
  static int b;
};

int main(int argc, char **argv)
{
  C c1;
  C c2;

  c1.a = 5;
  c2.a = 10;
  C::b = 15;

  printf("%d %d %d %d\n", c1.a, c2.a, c1.b, c2.b);
}
That prints "5 10 15 15" - c1 and c2 both get their own copy of "a", but share a copy of "b". And you can in fact access b without even having an object, by going through the class.

Python's the same, except you can actually reuse a name as both a static variable and an instance variable:

code:
class Name:
    foo = ""    # foo is part of the class.  Every Name shares the same foo.

    def set_variable(self, bar):
        # self is a copy of the individual Name object
        self.foo = bar  # this creates a new foo, part of the "self" object, which 
                        # is different from the foo that's part of the class

n1 = Name()
n2 = Name()

n1.set_variable("name1")
n2.set_variable("name2")

print n1.foo    # prints "name1"
print n2.foo    # prints "name2"
print Name.foo  # prints nothing, because Name.foo is still ""

ahobday
Apr 19, 2007

So the foo = "" isn't necessary at all, because I never set Name.foo to anything in my program.

And am I right in saying that passing "self" as an argument (Or are they called parameters?) is basically passing the object (Instance of a class) that you're calling at that moment?

So if I had two instances of Name: n1 and n2, then calling n1.set_variable("name") would be passing (n1, "name") to the set_variable function?

Or put more simply, is "self" essentially a variable that gets set to the name of whichever object you happen to be using at that point?

Adbot
ADBOT LOVES YOU

Scaevolus
Apr 16, 2007

Centipeed posted:

Or put more simply, is "self" essentially a variable that gets set to the name of whichever object you happen to be using at that point?

Yes.

This also means that if n1 is an instance of a class n, you can do n.some_function(n1, ...)

  • Locked thread