Re: [Tutor] Clash of the Titans and Mundane Matters
Michael Powe wrote: Clash of the Titans From "Dive into Python": __init__ is called immediately after an instance of the class is created. It would be tempting but incorrect to call this the constructor of the class. It's tempting, because it looks like a constructor (by convention, __init__ is the first method defined for the class), acts like one (it's the first piece of code executed in a newly created instance of the class), and even sounds like one ("init" certainly suggests a constructor-ish nature). Incorrect, because the object has already been constructed by the time __init__ is called, and you already have a valid reference to the new instance of the class. But __init__ is the closest thing you're going to get to a constructor in Python, and it fills much the same role. From Alan's book "Learning to Program": One of the methods of this class is called __init__ and it is a special method called a constructor. The reason for the name is that it is called when a new object instance is created or constructed. Any variables assigned (and hence created in Python) inside this method will be unique to the new instance. There are a number of special methods like this in Python, nearly all distinguished by the __xxx__ naming format. When thinking about __init__ think not "constructor" but "initializer" (that's where the name comes from after all...). By definition, an initializer initializes something already existing, already constructed. To *construct* a new instance one implements __new__ (python >= 2.2. See the docs). [text snipped] Finally, in terms of "understanding python," the question I keep coming up against is: why do we have both functions and methods? What is the rationale for making join() a string method and a os.path function? Because functions and methods are different objects for conceptually different things? The way I tend to think of it, is that methods are functions with a little bit of extra functionality (although in the current implementation of Python functions *are* methods, or more corectly, descriptors). For the second question, os.path would be a method of what class? Best regards, G. Rodrigues ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Clash of the Titans and Mundane Matters
Michael Powe wrote: Here's an example: in Java, I wrote an application to track my travelling expenses (I'm a consultant; this tracking of expenses is the itch I am constantly scratching. ;-) I've also written this application in a perl/CGI web application as well.) It's easy to see the outline of this task: create an abstract class for expense and then extend it for the particular types of expenses -- travel, food, transportation, lodging and so forth. In python, I guess I'd create a class and then "subclass" it. But ... what are reading/writing to files and printing? I'm not sure exactly what output you're after ... But what about something like this? class Expense(object): def __init__(self, amount): self.amount = amount class Travel(Expense): def __str__(self): return 'Travel: $%.2f' % float(self.amount) class Food(Expense): def __str__(self): return 'Food: $%.2f' % float(self.amount) class Accommodation(Expense): def __str__(self): return 'Accommodation: $%.2f' % float(self.amount) myExpenses = [Travel(2300), Accommodation(200), Food(12.50), Food(19.95), Food(2.35), Travel(500)] for e in myExpenses: print e out = file('myExpenses.txt', 'w') for e in myExpenses: out.write(str(e) + '\n') out.close() - This produces output: Travel: $2300.00 Accommodation: $200.00 Food: $12.50 Food: $19.95 Food: $2.35 Travel: $500.00 and the same in the file 'myExpenses.txt'. The str() function automatically calls .__str__() on its argument (if you don't define __str__, it will call a boring default one). And the print command automatically calls str() on its arguments. -- John. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
Re: [Tutor] Clash of the Titans and Mundane Matters
Michael Powe wrote: Clash of the Titans snip constructor discussions Pilgrim is pedantically correct but Alan's comment matches how most of us think about it. Mundane Matters I'm having a hard time with classes in python, but it's coming slowly. One thing that I think is generally difficult is to parse a task into "objects." Here's an example: in Java, I wrote an application to track my travelling expenses (I'm a consultant; this tracking of expenses is the itch I am constantly scratching. ;-) I've also written this application in a perl/CGI web application as well.) It's easy to see the outline of this task: create an abstract class for expense and then extend it for the particular types of expenses -- travel, food, transportation, lodging and so forth. In python, I guess I'd create a class and then "subclass" it. while that is a valid approach, it is not how most of us would do it. By subclassing you have to edit the code every time a new expense type is added. Ever used MS Money or Quicken? Imagine if the type of each item was a subclass. Use a string. A similar problem occurs with my HTML-parsing routine that I brought to the list recently. Use of HTMLParser was suggested. I've looked into this and usage means subclassing HTMLParser in order to implement the methods in the way that will accomplish my task. Conceptually, I'm having a hard time with the "object" here. (The fairly poor documentation for HTMLParser doesn't help.) Apparently, I'm creating a "parser" object and feeding it data. At least, that's the closest I can get to understanding this process. How I'm actually feeding data to the "parser" object and retrieving the results are matters open to discussion. I'll be working on that when I get another chance. This counts the tags in a html file piped in on stdin. #!/usr/bin/python import sys, HTMLParser class TagCounter(HTMLParser.HTMLParser): def __init__(self): HTMLParser.HTMLParser.__init__(self) self.tags = {} def handle_starttag(self, tag, attrs): self.tags[tag] = self.tags.setdefault(tag, 0) + 1 if __name__ == '__main__': counter = TagCounter() for line in sys.stdin.xreadlines(): counter.feed(line) counter.close() print counter.tags Finally, in terms of "understanding python," the question I keep coming up against is: why do we have both functions and methods? What is the rationale for making join() a string method and a os.path function? a method is a function bound to a class. Nothing super special. ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor
[Tutor] Clash of the Titans and Mundane Matters
Clash of the Titans >From "Dive into Python": __init__ is called immediately after an instance of the class is created. It would be tempting but incorrect to call this the constructor of the class. It's tempting, because it looks like a constructor (by convention, __init__ is the first method defined for the class), acts like one (it's the first piece of code executed in a newly created instance of the class), and even sounds like one ("init" certainly suggests a constructor-ish nature). Incorrect, because the object has already been constructed by the time __init__ is called, and you already have a valid reference to the new instance of the class. But __init__ is the closest thing you're going to get to a constructor in Python, and it fills much the same role. >From Alan's book "Learning to Program": One of the methods of this class is called __init__ and it is a special method called a constructor. The reason for the name is that it is called when a new object instance is created or constructed. Any variables assigned (and hence created in Python) inside this method will be unique to the new instance. There are a number of special methods like this in Python, nearly all distinguished by the __xxx__ naming format. Mundane Matters I'm having a hard time with classes in python, but it's coming slowly. One thing that I think is generally difficult is to parse a task into "objects." Here's an example: in Java, I wrote an application to track my travelling expenses (I'm a consultant; this tracking of expenses is the itch I am constantly scratching. ;-) I've also written this application in a perl/CGI web application as well.) It's easy to see the outline of this task: create an abstract class for expense and then extend it for the particular types of expenses -- travel, food, transportation, lodging and so forth. In python, I guess I'd create a class and then "subclass" it. But ... what are reading/writing to files and printing? Of course, I create a "file object" in order to accomplish these tasks -- but how is this object fit into the application design? Do I just create methods within the expense class to accomplish these parts of the task? When I tried this on, it seemed hacky. The other option seemed to be creating an I/O class and passing the expense objects to it. But, should that class be an interface or an object? The one thing you don't see in "how to program" java books is an implementation of I/O in the context of an application. A similar problem occurs with my HTML-parsing routine that I brought to the list recently. Use of HTMLParser was suggested. I've looked into this and usage means subclassing HTMLParser in order to implement the methods in the way that will accomplish my task. Conceptually, I'm having a hard time with the "object" here. (The fairly poor documentation for HTMLParser doesn't help.) Apparently, I'm creating a "parser" object and feeding it data. At least, that's the closest I can get to understanding this process. How I'm actually feeding data to the "parser" object and retrieving the results are matters open to discussion. I'll be working on that when I get another chance. Finally, in terms of "understanding python," the question I keep coming up against is: why do we have both functions and methods? What is the rationale for making join() a string method and a os.path function? Thanks for your time. It's late. ;-) Sometimes, I just have to get these things off my chest. mp ___ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor