On Oct 31, 2007 5:49 PM, Dustan <[EMAIL PROTECTED]> wrote: > On Oct 31, 7:08 am, Duncan Booth <[EMAIL PROTECTED]> wrote: > > > Dustan <[EMAIL PROTECTED]> wrote: > > > On Oct 30, 11:29 am, Duncan Booth <[EMAIL PROTECTED]> > > > wrote: > > >> Neil Cerutti <[EMAIL PROTECTED]> wrote: > > >> > It's allows a standard programming idiom which provides a > > >> > primitive form of object oriented programming using closures to > > >> > represent state. > > > > >> > def account(opening_balance): > > >> > balance = opening_balance > > >> > def get_balance(): > > >> > nonlocal balance > > >> > return balance > > >> > def post_transaction(x): > > >> > nonlocal balance > > >> > balance += x > > >> > return balance, post_transaction > > > > >> > fred_balance, fred_post = account(1500) > > >> > joe_balance, joe_post = account(12) > > >> > fred_post(20) > > >> > joe_post(-10) > > >> > fred_balance() > > > > >> TypeError: 'int' object is not callable > > > > >> > 1520 > > >> > joe_balance() > > > > >> TypeError: 'int' object is not callable > > > > >> > 2 > > > > >> > Python classes will of course nearly always win, though the idiom > > >> > looks like it might be faster (I don't have Python 3000 to try it > > >> > out). > > > > >> Python classes might be less error prone. > > > > > Why would using classes make your code any less prone to typographical > > > errors? > > > > Lots of reasons: shorter and clearer code being high on the list. > > It wouldn't be necessarily shorter, depending on what you're working > with. Clearer is a matter of opinion. >
It's going to be shorter in any non-trivial example, and even in most trivial ones (as shown). Clearer may be a matter of opinion, but the less complicated the code you're looking at is, the less chance you have to make an error. > > The > > class equivalent would be: > > > > >>> class Account(object): > > > > def __init__(self, opening_balance): > > self.balance = opening_balance > > > > def post_transaction(self, x): > > self.balance += x > > > > >>> fred = Account(1500) > > >>> joe = Account(12) > > >>> fred.post_transaction(20) > > >>> joe.post_transaction(-10) > > >>> fred.balance > > 1520 > > >>> joe.balance > > > > 2 > > > > There is no scope for the particular error I highlighted: you no longer > > have the duplication of declaring the functions and then returning them. > > The 'particular error' you highlighted was a typographical error, > which can happen in any code. Sure, you can't have the exact same > typographical error, but that's what happens when you switch between > paradigms. > By having fewer explicit things to manage, you lessen the scope of errors in naming those things. This is one reason why the DRY principle is advocated - the fewer times you type something, the fewer chances you have to typo it. > > Also you don't need the accessor function at all (and if at some point > > in the future you do want it you can make it a property). > > > > You don't have to invent separate names for each of the returned > > functions: the dot notation suddenly makes that a no brainer. > > Fair enough; you got two valid arguments there. > > > Also the class is easier to extend: you no longer have to find and > > change every call to account() if you want to add another method: just > > add it. > > Of course, there are cases where you'll never want to extend it. > Designing it in such a way that it's impossible to extend pretty much ensures that, doesn't it? I have no idea why someone who already has a working, object system would want to implement their own on top of closures. I'd even take issue with the idea that's it's a "standard" idiom for the quite uncommon task of creating object systems, it's a well known conceptual idea but it's not actually implemented as such very often. -- http://mail.python.org/mailman/listinfo/python-list