### Python Learning
《简明Python教程》笔记。
#@author: gr
#@date: 2014-06-30
#@email: forgerui@gmail.com
一、Basic Language
1.1. 输出
字符串的拼接:
count = 10
# 使用逗号会增加空格
print "hello", count, "people"
# 使用+不会增加空格
print "hello" + "world"
格式化输出:
my_name = 'Andy'
print "Hello %s" % my_name
显示变量的原始数据使用%r
。
answer = True
str = "are you good man? %r"
print str % answer
# 输出结果为are you good man? True
多个%情况:
print "%s %s" % ("hello", "world")
多行打印:
print """
hello world
hello kitty
"""
1.2. 输入
使用raw_input()
获取输入:
print "How old are you?",
age = raw_input()
age = input()
raw_input()
与input()
,这两个函数均能接收 字符串 ,但raw_input()
直接读取控制台的输入,而对于 input() ,它希望能够读取一个合法的 python 表达式,即你输入字符串的时候必须使用引号将它括起来。一般情况下使用raw_input()
。
让raw_input()
显示提示:
age = raw_input("How old are you? ")
1.3. 脚本参数
from sys import argv
# 输入的参数必须是3个,否则会报错
script, first, second, third = argv
1.4. 数学计算
指数:
# 输出2^10
print 2 ** 10
1.5. if
if
子句里的表达式需要缩进:
if a == b:
print 'the result is right'
else:
print 'the result is wrong'
1.5. while
while
可以包含一个else
从句:
i = 1
b = 10
while a <= b:
a++
print 'looping...'
else:
print 'The loop is over'
1.6. for
for...in
是递归第一个项目:
for i in range(0, 5):
print i
else:
print 'The for loop is over'
相当于C语言中的
for (int i = 0; i < 5; ++i)
1.7. 函数
def sayHello():
print 'hello world'
sayHello()
局部变量无法修改参数值,要想修改函数参数值,使用global
修饰:
i = 3
def test():
global i
i = 5
print "the value before changed:", i
test()
print "the value after changed:", i
函数默认值:
def say(message, times = 1):
print message * times
say('Hello')
say('Hello', 5)
1.8. 关键参数
如果你的某个函数有许多参数,而你只想指定其中的一部分,那么你可以通过命名来为这些参数赋值。
def func(a, b = 5, c = 10):
print 'a is', a, 'and b is', b, 'and c is', c
func(3, 7)
func(25, c=24)
func(c=50, a=100)
1.9. return
return
语句用来返回函数的返回值,如果没有返回值的return
,则等价于return None
。
1.10. pass
如果函数是一个空块,不需要写任何东西,用pass
表示。
# 是个空函数,什么也不做
def foobar():
pass
1.11. DocStrings
DocStrings可以你的程序文档更加简单易懂,也可以在程序运行的时候,从函数恢复文档字符串。
def printMax(x, y):
'''Prints the maximum of two numbers.
The two values must be integers.'''
x = int(x)
y = int(y)
if x > y:
print x, 'is maximum'
else
print y, 'is maximum'
printMax(3, 5)
# 打印函数文档
print printMax.__doc__
DocStrings也适用于模块和类。
1.12. import
import sys
for i in sys.argv:
print i
如果想直接使用argv变量,可以使用from...import...
:
from sys import argv
for i in argv
print i
1.13. __name__
模块名称应用的一个地方就是当程序本身被使用时候运行主块,而它被别的模块输入的时候不运行主块。
if __name__ == '__main__':
print 'This program is being run by itself'
else:
print 'I am being imported from another module'
1.14. 编写自己的模块
#!/usr/bin/bash
# Filename: mymodule.py
def sayHi():
print 'this is the sayHi function of mymodule'
version = 1.0
#!/usr/bin/bash
# Filename: test_mymodule.py
import mymodule
mymodule.sayHi()
print 'the version of mymodule is', mymodule.version
1.15. dir()
dir()
函数用于列出模块中定义的标识符,标识符可以是函数、类和变量。如果不提供参数,它返回当前模块中定义的名称列表。
可以使用del
语句删除当前模块中的变量/属性。
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'sys']
>>> a = 5
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'a', 'sys']
>>> del a
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'sys']
二、数据结构
2.1. 列表
list
是处理一组有序项目的数据结构,即你可以在一个列表中存储一个 序列 的项目。
list
是一个类。Python为list
提供一系列方法,如append
, count
, index
等。
shopList = ['apple', 'mango', 'banna']
print 'I have', len(shopList), 'items to buy'
print 'these items are:',
for item in shopList:
print item,
print '\n I alse have to buy rice'
shopList.append('rice')
print 'My shopping list is now', shopList
print 'I will sort my list'
shopList.sort()
print 'Sorted shopping list is', shopList
print 'The first term I will buy is', shoplist[0]
oldItem = shoplist[0]
del shopList[0]
print 'I bought the', oldItem
print 'My shopping list is now', shopList
2.2. 元组
元组和列表十分相似,但元组和字符串一样是不可变的,你不能修改元组。它使用小括号中用逗号分割项目。
zoo = ('wolf', 'elephant', 'penguin')
print 'Number of animals in the zoo is', len(zoo)
new_zoo = ('monkey', 'dolphin', zoo)
print 'Number of animals in the new zoo is', len(new_zoo)
print 'All animals in new zoo are', new_zoo
print 'Animals brought from old zoo are', new_zoo[2]
print 'Last animal brought from old zoo is', new_zoo[2][2]
含有0个项目的元组可以用空的圆括号表示:
myempty = ()
含有单个元素的元组必须在第一个项目后加一个逗号,这样才能区分元组和一个带圆括号的对象。
single = (2, )
元组用于打印语句:
age = 22
name = 'Andy'
print '%s is %d years old' % (name, age)
2.3. 字典
只能使用不可变的对象(比如字符串)来作为字典的键。键值对在字典中以这样的方式标记:d = {key1:value1, key2:value2}
,键值对冒号分割,各个对用逗号分割。
ab = {'gr': 24, 'Andy':22, 'Lucy':34}
print "gr's age is %d" % ab['gr']
ab['Daniel'] = 27
del ab['Andy']
print '\n There are %d pepole' % len(ab)
for name, age in ab.items():
print '%s is %d years old' % (name, age)
if 'Daniel' in ab: # OR ab.has_key('Daniel')
print 'Daniel is %d years old' % ab['Daniel']
2.4. 序列
列表、元组和字符串都是序列,两个主要特点是索引操作和切片操作。索引获取一个特定项目,切片操作获取序列一部分。
shoplist = ['apple', 'mango', 'carrot', 'banana']
# index
print 'Item 0 is', shoplist[0]
print 'Item -1 is', shoplist[-1]
# slice
print 'Item 1 to 3 is', shoplist[1:3]
print 'Item 1 to end is', shoplist[1:]
print 'Item 1 to -1 is', shoplist[1:-1]
print 'Item start to end is', shoplist[:]
2.5. 引用
当创建一个对象并给它赋一个变量时,这个对象是变量的别名,它们指向同一个地方。
#reference and slice copy
# reference
shoplist = ['apple', 'mango', 'carrot', 'banana']
mylist = shoplist
del shoplist[0] #mylist, shoplist都改变,保持一致
# slice copy
mylist = shoplist[:]
del shoplist[0] #mylist, shoplist不一样,shoplist少一项
2.6. 字符串类
字符串也是对象,同样具有方法。
name = 'Swaroop'
if name.startswith('Swa'):
print 'Yes, the string starts with "Swa"'
if 'a' in name:
print 'Yes, it contains the string "a"'
if name.find('war') != -1:
print 'Yes, it contains the string "war"'
delimiter = '_*_'
mylist = ['Brazil', 'Russia', 'India', 'China']
print delimiter.join(mylist)
三、面向对象编程
3.1. self参数
类的方法与普通的函数只有一个特别的区别,它们必须有一个额外的第一个参数名称,但是在调用这个方法的时候,你不为这个参数赋值,Python会提供这个值。这个变量指对象本身,按照惯例它的名称是self
。
假设有一个类称为MyClass
和这个类的一个实例MyObject
,当你调用这个对象的方法MyObject.method(arg1, arg2)
时,Python会自动转换成MyClass.method(MyObject, arg1, arg2)
。
3.2. 类
class Person:
pass
p = Person()
print p
3.3. init
Python中有很多方法的名字有特殊的重要意义。__init__
方法在类的一个对象被建立时,马上运行。它可以用来对你的对象做一些初始化。
class Person:
def __init__(self, name):
self.name = name
def sayHi(self):
print 'Hello, my name is', self.name
p = Person('Andy')
p.sayHi()
3.4. 类与对象
类的变量和对象的变量:根据是为还是对象拥有这个变量而区分。
类的变量由一个类的所有对象共享使用,当某个对象修改类变量时,这个改动会反映到所有其他的实例上。
对象的变量由类的每个对象拥有,在一个类的不同实例中,虽然对象变量有相同的名称,但是互不相关的。
class Person:
population = 0
def __init__(self, name):
self.name = name
print '(Initializing %s)' % self.name
Person.population += 1
def __del__(self):
print '%s says bye.' % self.name
Person.population -= 1
if Person.population == 0:
print 'I am the last one.'
else:
print 'There are still %d people left.' % Person.population
def sayHi(self):
print 'Hi, my name is %s.' % self.name
def howMany(self):
if Person.population == 1:
print 'I am the only person here.'
else:
print 'we have %d persons here.' % Person.population
andy = Person('Andy')
andy.sayHi()
andy.howMany()
kalam = Person('Kalam')
kalam.sayHi()
kalam.howMany()
andy.sayHi()
andy.howMany()
3.5. 继承
通过继承可以实现代码重用。
class SchoolMember:
'''Represents any school member.'''
def __init__(self, name, age):
self.name = name
self.age = age
print '(Initialized SchoolMember:%s)' % self.name
def tell(self):
'''Tell my details.'''
print 'Name:"%s" Age:"%s"' % (self.name,self.age),
class Teacher(SchoolMember):
'''Represents a teacher.'''
def __init__(self, name, age, salary):
SchoolMember.__init__(self, name, age)
self.salary = salary
print '(Initialized Teacher: %s)' % self.name
def tell(self):
SchoolMember.tell(self)
print 'Salary: "%d"' % self.salary
class Student(SchoolMember):
'''Represents a student.'''
def __init__(self, name, age, marks):
SchoolMember.__init__(self, name, age)
self.marks = marks
print '(Initialized Student: %s)' % self.name
def tell(self):
SchoolMember.tell(self)
print 'Marks: "%d"' % self.marks
t = Teacher('Mrs. Shrividya', 40, 30000)
s = Student('Swaroop', 22, 75)
print # prints a blank line
members = [t, s]
for member in members:
member.tell() # works for both Teachers and Students
四、文件
4.1. 文件
通过创建一个file
类对象打开一个文件,分别使用file
类的read
,readline
或write
方法恰当地读写文件。
poem = '''
program is fun
when the work is done
if you wanna make your work also fun:
use Python!
'''
f = file('poem.txt', 'w')
f.write(poem)
f.close()
f = file('poem.txt')
while True:
line = f.readline()
if len(line) == 0:
break;
print line,
f.close()
4.2. 储存器
Python提供一个标准的模块,称为pickle
。使用它你可以在一个文件中储存任何Python对象,之后你以可以把它完整无缺地取出来。这称为持久地储存对象。
cPickle
的功能和pickle
模块完全相同,只不过它是用C语言编写,因此要快得多。
import cPickle as p
shoplistfile = 'shoplist.data'
shoplist = ['apple', 'mango', 'carrot']
f = file(shoplistfile, 'w')
p.dump(shoplist, f)
f.close()
del shoplist
f = file(shoplistfile)
storedlist = p.load(f)
print storedlist
五、异常
5.1. try ... except
import sys
try:
s = raw_input('Enter something --> ')
except EOFError:
print '\nWhy did you do an EOF on me?'
sys.exit()
except:
print '\nSome error/exception occurred.'
print 'Done'
5.2. 抛出异常
可以使用raise
引发异常,还得指明错误/异常的名称和伴随异常触发的异常对象。
class ShortInputException(Exception):
'''A user-defined exception class.'''
def __init__(self, length, atleast):
Exception.__init__(self)
self.length = length
self.atleast = atleast
try:
s = raw_input('Enter something-->')
if len(s) < 3:
raise ShortInputException(len(s), 3)
except EOFError:
print '\n Why did you do an EOF on me?'
except ShortInputException, x:
print 'ShortInputException: The input was of length %d, \
was expecting at least %d' % (x.length, x.atleast)
else:
print 'No exception was raised.
5.3. try...finally
希望无论异常发生与否都关闭文件,这时可以使用try...finally
。
import time
try:
f = file('poem.txt')
while True:
line = f.readline()
if len(line) == 0:
break
time.sleep(2)
print line,
finally:
f.close()
print 'Cleaning up...closed the file'
六、Python标准库
6.1. sys模块
import sys
def readfile(filename):
'''Print a file to the standard output'''
f = file(filename)
while True:
line = f.readline()
if len(line) == 0:
break
print line,
f.close()
if len(sys.argv) < 2:
print 'No action specified.'
sys.exit()
if sys.argv[1].startswith('--'):
option = sys.argv[1][2:]
if option == 'version':
print 'Version 1.2'
elif option == 'help':
print '''\
This program prints files to the standard output.
Any number of files can be specified.
Options include:
--version : Prints the version number
--help : Display this help'''
else:
print 'Unknown option.'
sys.exit()
else:
for filename in sys.argv[1:]:
readfile(filename)
6.2. os模块
这个模块包含普遍的操作系统功能。如果你希望你的程序能够与平台无关的话,这个模块是尤为重要。
- os.name() #Windows,它是'nt';对于Linux/Unix用户,它是'posix'
- os.getenv() #得到当前工作目录,即当前Python脚本工作的目录路径
- os.listdir() #返回指定目录下的所有文件和目录名
- os.remove() #函数用来删除一个文件
- os.system() #函数用来运行shell命令
- os.path.split() #函数返回一个路径的目录名和文件名
七、其它
7.1. 单语句块
如果你的语句块只包含一句语句,那么你可以在条件语句或循环语句的同一行指明它。
>>> flag = True
>>> if flag: print 'Yes'
...
Yes
单个语句被直接使用而不是作为一个独立的块使用。
7.2. 列表综合
通过一个已有的列表导出一个新的列表。例如,你有一个数的列表,而你想要得到一个对应的列表,使其中所有大于2的数都是原来的2倍。对于这种应用,列表综合是最理想的方法。
listone = [2, 3, 4]
listtwo = [2*i for i in listone if i > 2]
print listtwo
7.3. 在函数中接收元组和列表
当要使用函数接收元组或字典形式的参数的时候,有一种特殊的方法,它分别使用×
和**
前缀。这种方法方法在函数需要获取可变数量的参数的时候特别有用。
def powersum(power, *args):
total = 0
for i in args:
total += pow(i, power)
return total
powersum(2, 3, 4)
powersum(2, 10)
使用*
做为前缀,所有多余的函数参数都会作为一个元组存储在args
中,如果使用的是**
前缀,多余的参数则会被认为是一个字典的键/值对。
7.4. lambda形式
lambda
语句被用来创建新的函数对象,并且在运行时返回它们。
def make_repeater(n):
return lambda s:s*n
twice = make_repeater(2)
print twice('word')
print twice(5)
make_repeater 函数在运行时创建新的函数对象,并且返回它。lambda语句用来创建函数对象。本质上,lambda需要一个参数,后面仅跟单个表达式作为函数体,而表达式的值被这个新建的函数返回。
7.5. exec, eval
exec
用来执行储存在字符串或文件中的Python语句。例如,我们可以在运行时生成一个包含Python代码的字符串,然后使用exec语句执行这些语句:
exec 'print "hello world"'
eval
语句用来计算存储在字符串中的有效Python表达式。
eval('2*3')
7.6. assert
assert
用来声明某个条件是真的。当assert
语句失败时,会引发一个AssertionError
。
mylist = ['item']
assert len(mylist) >= 1
mylist.pop()
assert len(mylist) >= 1
#Traceback (most recent call last):
# File "<stdin>", line 4, in ?
#AssertionError
7.7 repr
repr
函数用来取得对象的规范字符串表示。反引号可以完成相同的功能。大多数时候有eval(repr(object)) == object
。
i = []
i.append('item')
>>> `i`
"['item']"
>>> repr(i)
"['item']"
基本上,repr
函数和反引号用来获取对象的可打印的表示形式。你可以通过定义类的__repr__
方法来控制你的对象在被repr
函数调用的时候返回的内容。