![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
Advanced Python Tricks
Python is a language that is often underestimated, and often underused. Beneath its deceptively simple exterior, Python has some very powerful features that you may not be aware of. This post will introduce you to some of these less well known corners of the Python programming language.
(If you're a Python guru, feel free to ignore this )Properties Properties gives Python all the advantages of getter and setter functions, along with the convenience of normal object variables. To show you what I mean, consider a class ExamResult with a variable called score. Like most exam results, the score is a percentage, and can be anything from 0 to 100. A score above 100, or below 0, is clearly invalid. Traditionally, we might write a class with some getter and setter functions: class ExamResult:
def __init__(self, score = 0):
self.set_score(score)
def get_score(self):
return self.__score
def set_score(self, score):
if (score < 0) or (score > 100):
raise ValueError
else:
self.__score = score
result = ExamResult()
try:
result.set_score(110)
except ValueError:
print "Cannot score more than 100%"
result.set_score(79)
print "Exam score: %d%%" % result.get_score()class ExamResult(object):
def __init__(self, score = 0):
self.set_score(score)
def get_score(self):
return self.__score
def set_score(self, score):
if (score < 0) or (score > 100):
raise ValueError
else:
self.__score = score
score = property(get_score, set_score)
result = ExamResult()
try:
result.score = 110
except ValueError:
print "Cannot score more than 100%"
result.score = 79
print "Exam score: %d%%" % result.scoreHigher Order Functions Most functions take in and return variables and values. Higher order functions take in and return other functions. This is an important and powerful concept in programming; rather than manipulating data, you're manipulating code. To demonstrate this, here's a simple higher-order addition function: def add(x):
def inc(y):
return x + y
return incTo use this function to add up two numbers, we call it twice over: inc = add(1) inc(10) # returns 11 add(9)(5) # returns 14 Generators All python programmers are familiar with for-loops, and their ability to iterate over a list. What some programmers may not know, is that you can also use generator functions. For instance, take the humble range function, which returns a list of incremental numbers. This is useful enough in some cases, but less useful when used in a for-loop that will run for thousands of iterations: for i in range(10000): # do something An easy way is to use a generator function and the yield keyword: def quick_range(x):
i = 0
while i < x:
yield i
i += 1
for i in quick_range(10000):
# do somethingThis generator function can be used in for loops in much the same way as a list is. It's also faster, since there is no need to allocate memory for a 10'000 member list. Because iterating over large numbers is a common problem, Python supplies the xrange function, which is similar in nature to the quick_range function, as supplied above. Using xrange when dealing with large numbers can dramatically increase the efficiency of your program. Assertions Java programmers will (hopefully!) be familiar with assertions. Simply put, an assertion is a test that raises an AssertionError if the test fails. Assertions are a valuable debugging tool, as they prevent errors propagating through your software by catching them early. Take this buggy code: def get_year_from_user():
year = raw_input("Enter your birth year: ")
if (year == 2006):
raise ValueError, "That year has not happened yet"
return year
def get_age_from_year(year):
age = 2005 - year
return "You are either %d or %d years old" % (age, age - 1)
user_year = get_year_from_user()
print get_age_from_year(user_year)def get_age_from_year(year): age = 2005 - year assert age >= 0 return "You are either %d or %d years old" % (age, age - 1) Fun with lists Python has some very powerful functionality for handling lists. Everyone knows about the "in" keyword when in a for-loop: for i in range(10): pass contained within a list: if user_fruit in ['apple', 'banana', 'grapefruit']: print "Valid fruit" [i * i for i in range(10)] [i for i in range(10) if (i % 2) == 0] Last edited by Arevos; Sep 18th, 2005 at 11:22 AM. |
|
|
|
|
|
#2 |
|
Expert Programmer
|
Nice article =) maybe it could be stickyed
![]() It may get soem more python users among us ![]() Another thing I would like to point out is the os module. In Python there is a standard module called os. I believe that every function in it is multiplatform, but i will probably be corrected. As you know in Windows a file path uses backslashes. Example: \data_files\save_games\save1.dat In Unix we use forward slash. Example: /home/user_name/game/save_games/save1.dat So if you wanted to load somethign from another folder, in another programming langauge, you would have to first check which operating system it is being run on, then use an if statement to choose wether to use / or \. With the os module you can simply use the join() function. #Platform independent!
import os
os.join("data","save_games")
__________________
Join us at #programmingforums @ irc.freenode.net! My software never has bugs. It just develops random features.
|
|
|
|
|
|
#3 |
|
I eat cake for breakfast.
![]() ![]() ![]() ![]() Join Date: Jul 2004
Location: In my box.
Posts: 4,434
Rep Power: 9
![]() |
I think this thread is about language features, not specific libraries. Anyway, nice work Arevos. I'll be bookmarking this one.
|
|
|
|
|
|
#4 | |
|
Professional Programmer
Join Date: Apr 2005
Location: London, England
Posts: 459
Rep Power: 4
![]() |
But the standard library and Python's features go hand in hand.
Quote:
# Calls a function, passing each item in the list and returning the new list map(str, [2, 3, 5, 1]) == [str(x) for x in [2, 3, 5, 1]] # Filters out items in a list based on whether or not the function the item is passed to returns True or False filter(bool, [1, 0, 3, 1, 0]) == [x for x in [1, 0, 3, 1, 0] if bool(x)] def foo(x):
return x == 2
# is the same as
foo = lambda x: x == 2
# but you can use lambda inline.
# e.g filter out every number in the list that isn't a 2
filter(lambda x: x == 2, [2, 1, 4, 2, 5, 3]) |
|
|
|
|
|
|
#5 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
lambdas are being talked being depreciated in Python, though, based on the thinking that they're not really needed.
|
|
|
|
|
|
#6 |
|
Professional Programmer
Join Date: Apr 2005
Location: London, England
Posts: 459
Rep Power: 4
![]() |
Yeah, Guido really wants them out for Python 3.0. That's more than fine now that they've introduced list comps, though. I primarily put the examples there for people that may come to maintain code that uses them.
|
|
|
|
|
|
#7 | |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 5
![]() |
Quote:
![]() |
|
|
|
|
|
|
#8 |
|
Troll
Join Date: Apr 2005
Location: Texas
Posts: 732
Rep Power: 4
![]() |
Just as C# decides to put them in
![]()
__________________
MD5(sig) = bcef75433db02e9ad9bf81d6f7c5c270 |
|
|
|
|
|
#9 | |
|
Professional Programmer
Join Date: Feb 2005
Posts: 434
Rep Power: 4
![]() |
Quote:
__________________
I looked it up on the Intergnats! |
|
|
|
|
|
|
#10 | |
|
Professional Programmer
Join Date: Feb 2005
Posts: 434
Rep Power: 4
![]() |
Quote:
# Python can do a switch/case like thingy using a dictionary and lambda
# basis for a nice calculator
def do_operation(op, a, b):
"""here a dictionary combined with the lambda inline function acts like switch/case"""
return {'+': lambda: a + b,
'-': lambda: a - b,
'*': lambda: a * b,
'/': lambda: a / b
}[op]()
print do_operation('+', 2, 5)
__________________
I looked it up on the Intergnats! |
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|