September 19, 2004

Closures in Python (part 1)

Martin Fowler (obligitary Fowlbot namedrop) recently blogged about the power of closures in languages that support them. Here's a translation of Martin's Ruby code into Python. [Initial sentence and table structure copied from Joe Walnes] (not knowing how to get this to format correctly is my fault. I want to write a part 2, but that'll have to wait as I have other commitments (who are currently calling for me!) (now done)
Ruby Python (Direct translation, using "lambda")
def managers(emps)
  return emps.select {|e| e.isManager}
end
def managers(emps): 
        return filter(lambda e: e.isManager, emps) 
def highPaid(emps)
  threshold = 150
  return emps.select {|e| e.salary > threshold}
end
def highPaid(emps): 
        threshold = 150 
        return filter(lambda e: e.salary > threshold, emps) 
def paidMore(amount)
  return Proc.new {|e| e.salary > amount}
end
def paidMore(amount): 
        return lambda e: e.salary > amount
highPaid = paidMore(150)
john = Employee.new
john.salary = 200
print highPaid.call(john)
highPaid = paidMore(150)
john = Employee()
john.salary = 200
print highPaid(john)
Ruby Python (Idiomatic translation, using "list comprehensions")
def managers(emps)
  return emps.select {|e| e.isManager}
end
def managers(emps): 
        return [e for e in emps if e.isManager]
def highPaid(emps)
  threshold = 150
  return emps.select {|e| e.salary > threshold}
end
def highPaid(emps): 
        threshold = 150 
        return [e for e in emps if e.salary > threshold]
Posted by ivan at September 19, 2004 9:22 AM
Copyright (c) 2004-2008 Ivan Moore
Comments

I'm new too python, so used lambda in this simple wc.py app..

I was wondering if there would be a better way to do this??? Thanks..


import sys
files = map(lambda f: open(f), sys.argv[1:])
Twords = Tlines = Tchars = 0
for file in files:
   words = lines = chars = 0
   for line in file.xreadlines():
      lines += 1
      words += len(line.split())
      chars += len(line)
   print lines, words, chars, file.name

   Twords += words
   Tlines += lines
   Tchars += chars
if len(sys.argv) > 2:
   print " total" % (Tlines, Twords, Tchars)

Posted by: Rick Beacham at January 26, 2005 8:28 AM

You could write:

files = [open(f) for f in sys.argv[1:]]

instead of:

files = map(lambda f: open(f), sys.argv[1:])

(ie. use a "list comprehension" - I think it reads a bit easier than using the map/lambda).

Ivan

Posted by: Ivan at January 26, 2005 9:45 PM