Chinaunix
标题:
Python的入门简介
[打印本页]
作者:
missjiang
时间:
2007-09-25 12:28
标题:
Python的入门简介
前段时间老板要做一个项目,采用的开发语言是Python,之前本人只学习过C++和Java两种传统的编程语言,对于Python语言的了解仅限于听说过而已,在参与这个项目过程中,真真实实感受到了Python语言的简单易用和它的快速开发的效率。
我想可能部分网友和我有着相似的学习背景(只学习过传统的C++/Java编程语言,而对Perl/Python/Ruby没有了解),经历这个项目后,我认为像Python这样的语言确实有学习的必要,因此把我的Python学习笔记贴出来,不过前面部分写的过于基础了。
目录
1、第一个Python脚本: hello world
2、Python语言与传统的C++/Java语言显著不同的地方
3、Python语言的控制结构
4、变量声明和定义
5、函数
6、列表、字典、元组
7、字符串处理
8、面向对象编程:封装、继承、虚拟函数、接口、多继承、模板
9、面向对象编程:异常处理
[
本帖最后由 missjiang 于 2007-9-25 12:37 编辑
]
作者:
missjiang
时间:
2007-09-25 12:29
1、第一个Python脚本: hello world
#!/usr/bin/python
print 'hello world'
复制代码
与C语言的不同地方在于:
不需要使用 ; 结尾
不需要使用 () 把参数包起来
可以使用单引号
这些做法可以使得程序看上去较为清爽,当然如果你不习惯的话,Python编译器也可以接受以下的风格
#!/usr/bin/python
print("hello world");
复制代码
作者:
missjiang
时间:
2007-09-25 12:29
2、Python语言与传统的C++/Java语言显著不同的地方
变量在使用之前无须声明
a = 1
b = "hello world"
复制代码
使用 # 而不是//和/* ... */注释代码
c = a + b # this is comment
复制代码
表达式语句不需要使用 ; 结尾
a = a + 1
b = b + 1
复制代码
函数调用时不需要使用 () 把参数包起来,if/while 中的也不需要使用()把条件表达式包起来
print "hello world"
if a == b:
print 'a == b'
else:
print 'a != b'
复制代码
引号有单引号、双引号、三引号三种形式,后面详述
使用“缩进”而不是{}标志代码块
,下面我们将详细讨论这样作的优缺点.
先看一个例子:
a = 1
b = 2
c = 3
d = 3
if a == b:
if c == d:
print 'a == b && c == d'
else:
print 'a != b'
# 程序运行结果:a != b
复制代码
注意:
缩进相同的语句处于同一个语法块中
在if/else语句末尾有一个冒号,代表语法块的开始
python中提供了pass语句,该条语句表示一个空操作
a = 1
b = 2
if a == b:
pass
else:
print 'a != b'
# 程序运行结果:a != b
复制代码
Python语言这种做法的优点在于:
省去{}或者begin/end,使得程序结构更为清晰(也许有人会有不同的观点):
强制所有的Python程序都有着相同的风格,不会像在C语言中出现风格迥异的情况:
/* K&R的风格 */
if (a > b) {
printf("a > b")
}
/* 很多人喜欢的风格 */
if (a > b)
{
printf("a > b")
}
/* EMACS编辑器的风格 */
if (a > b)
{
printf("a > b")
}
复制代码
避免了如下情况由于忘记{}而造成的错误
#include <stdio.h>
int main()
{
int a, b, c, d;
a = 1;
b = 2;
c = 3;
d = 3;
if (a == b)
if (c == d)
puts("a == b && c == d");
else
puts("a != b");
return 0;
}
复制代码
从缩进来看,编写这段代码的程序员的本意是希望当a、b不相等时输出"a != b",但是程序运行时没有任何输出,和程序员期待的结果是不一样的。
Python语言这种做法的缺点在于:
python的代码一旦缩进乱了,无法重新格式化
粘贴代码的时候,缩进会被破坏,不方便
这些缺点倒是可以接受,关键在于用户是否认同Python缩进的优点。
作者:
missjiang
时间:
2007-09-25 12:30
3、Python语言的控制结构
if 语句
a = 1
b = 2
if a < b:
print 'a < b'
elif a == b:
print 'a == b'
else:
print 'a > b'
复制代码
注意:Python中提供了elif语句,是else if的缩写。
switch 语句
python没有提供switch 语句,另外python也不提供++、--运算符。
while 语句
sum = 0
i = 1
while i < 101:
sum += i
i += 1
else:
print("LOOP IS OVER, i = %d" % i) # 格式化字符串输出的细节在后面详述
print("sum = %d" % sum)
复制代码
程序运行结果:
LOOP IS OVER, i = 101
sum = 5050
while循环中的else语句
while循环中有一个可选的else语句,当循环没有被break中断而结束时,执行else后面的语句块,如果把程序改为:
sum = 0
i = 1
while i < 101:
sum += i
i += 1
break
else:
print("LOOP IS OVER, i = %d" % i)
print("sum = %d" % sum)
复制代码
程序运行结果变为:
sum = 1
for 语句
python中不提供C语言风格的for循环,如下代码段是不被接受的:
for (i = 1; i < 101; i += 1):
sum += i
复制代码
要计算从1累加到100的和,通常使用如下方法:
sum = 0
for i in range(1, 101):
sum += i
else:
print "LOOP IS OVER, i = %d" % i
print "sum is %d" % sum
复制代码
运行结果:
LOOP IS OVER, i = 100
sum = 5050
这里需要注意的是:
range(start, end, step)接受了三个参数:以步长为step(缺省为1),产生从start(包含)开始到end(不包含)结束的一个序列。在这个例子中,start = 1, end = 101, step = 1(缺省值),产生了从1到100总计100个数。
使用i变量遍历range产生的序列,循环执行100次,i的值依次为1、2、... 100。
for循环也有可选的else语句,功能和while循环中的else语句相同。
for 语句,指定range的step
for i in range(10, 0, -1):
print i
程序输出结果:
10
9
8
7
6
5
4
3
2
1
复制代码
在这个例子中,start = 10, end = 0, step = -1,程序的功能类似于如下C代码:
start = 10
end = 0
step = -1
for (i = start; i > end; i += step)
print(i)
复制代码
作者:
missjiang
时间:
2007-09-25 12:31
4、变量声明和定义
变量在使用之前无须声明
var = 1
print var
复制代码
变量在使用之前必须定义
print var
# 运行时刻出错,NameError: name 'var' is not defined
复制代码
定义变量时,可以获知变量的类型,需要记住列表、字典、元组使用不同的括号[]、{}、()
# 整数
integer = 123
# 字符串
string = "hello"
# 列表
list = [1, 2, 3]
# 字典
dict = {1:2, 2:4, 3:6}
# 元组
tuple = (1, 2, 3)
复制代码
在函数中缺省访问的是局部变量,当使用global声明后,访问的才是全局变量
def func():
g = 2 # 局部变量
g = 1
func()
print(g)
复制代码
func中修改了局部变量g,没有影响全局变量g,输出结果为1
def func():
global g
g = 2 # 全局变量
g = 1
func()
print(g)
复制代码
func中修改了全局变量g,输出结果为2
作者:
missjiang
时间:
2007-09-25 12:31
5、函数
使用def定义函数
def add(a, b):
return a + b
print(add(1, 2))
复制代码
运行结果为3
函数可以递归调用
def fact(n):
if n == 0:
return 1
else:
return n * fact(n - 1)
print(fact(3))
复制代码
运行结果为6
缺省参数
def func(a = 'a', b = 'b', c = 'c', d = 'd', e = 'e', f = 'f'):
print a + b + c + d + e + f
# 情况1:所有参数使用缺省值
# 输出结果:abcdef
func()
# 情况2:前面的参数使用指定值,后面的参数使用缺省值
# 输出结果:ABCdef
func('A', 'B', 'C')
# 情况3:任意指定哪些参数接受缺省值,哪些参数使用指定值
# 输出结果:aBcDeF
func(b = 'B', d = 'D', f = 'F')
复制代码
把所有的参数存放在数组中
add函数把接受的参数相加,并把和打印出来,注意args前面有一个*
def add(*args):
sum = 0
for i in args: # 遍历数组
sum += i
print sum
# 情况1:所有参数使用缺省值
# 输出结果:abcdef
func()
# 情况2:前面的参数使用指定值,后面的参数使用缺省值
# 输出结果:ABCdef
func('A', 'B', 'C')
# 情况3:任意指定哪些参数接受缺省值,哪些参数使用指定值
# 输出结果:aBcDeF
func(b = 'B', d = 'D', f = 'F')
复制代码
使用lambda生成一个新的函数
def generate_multiplier(factor):
return lambda x: x * factor
# 生成一个功能为乘以2的函数mul2,输出结果为200,mul2的定义相当于:
# def mul2(x):
# return x * 2
mul2 = generate_multiplier(2)
print(mul2(100))
# 生成一个功能为乘以4的函数mul4,输出结果为400,mul4的定义相当于:
# def mul4(x):
# return x * 4
mul4 = generate_multiplier(4)
print(mul4(100))
# 生成一个功能为乘以8的函数mul8,输出结果为800,mul8的定义相当于:
# def mul8(x):
# return x * 8
mul8 = generate_multiplier(8)
print(mul8(100))
复制代码
作者:
missjiang
时间:
2007-09-25 12:32
6、列表、字典、元组
待续...
作者:
missjiang
时间:
2007-09-25 12:32
7、字符串处理
待续...
作者:
missjiang
时间:
2007-09-25 12:33
8、面向对象编程:封装、继承、虚拟函数、接口、多继承、模板
Python是一种典型的动态类型语言,由于他的动态性:
天生支持虚拟函数、接口、模板等特征,无须引入特定的关键字
在多继承中不存在“菱形继承”引发的问题
下面我们通过举例的方式学习面向对象语言中的各种特性
1、封装
class Person:
def __init__(self, name):
self.name = name
def getName(self):
return self.name
person = Person('person')
print 'name = %s' % person.getName()
程序输出:
name = person
复制代码
与C++不同的地方:
类的成员函数的第一个参数是指向这个对象的self引用
在成员函数里,必须通过self引用访问其他的成员变量或者成员函数
class Person:
def __init__(self, name):
self.name = name
getName()
def getName(self):
return self.name
person = Person('person')
print 'name = %s' % person.getName()
运行时刻出错,NameError: global name 'getName' is not defined
复制代码
构造函数的名称为__init__
2、继承
class Chinese(Person):
def __init__(self, name, company):
Person.__init__(self, name)
self.company = company
def love(self):
print '%s is Chinese, he love working' % self.name
def work(self):
print '%s is working in %s' % (self.name, self.company)
class Japanese(Person):
def __init__(self, name, interesting):
Person.__init__(self, name)
self.interesting = interesting
def love(self):
print '%s is Japanese, he love playing' % self.name
def play(self):
print '%s is playing %s' % (self.name, self.interesting)
zhangSan = Chinese('Zhang San', 'HuaWei')
zhangSan.love()
zhangSan.work()
sanJing = Japanese('San Jing', 'Basketball')
sanJing.love()
sanJing.play()
程序输出:
Zhang San is Chinese, he love working
Zhang San is working in HuaWei
San Jing is Japanese, he love playing
San Jing is playing Basketball
复制代码
3、虚拟函数
zhangSan = Chinese('Zhang San', 'Hua Wei')
sanJing = Japanese('San Jing', 'Basketball')
persons = [zhangSan, sanJing]
for person in persons:
person.love()
程序输出:
Zhang San is Chinese, he love working
San Jing is Japanese, he love playing
复制代码
这个例子建立了继承于Person的Chinese和Japanese类,Chinese中定义了love和work两个成员函数,Japanese中定义了love和play两个成员函数,注意:
Python中没有virtual关键字,默认成员函数都是虚函数,这一点与java类似。
在Chinese和Japanese的父类Person中无须声明两者共同的接口(love函数),这一点与java不同
4、接口
class Cat:
def __init__(self, name, food):
self.name = name
self.food = food
def love(self):
print '%s is Cat, he love eating %s' % (self.name, self.food)
def callLove(object):
object.love()
zhangSan = Chinese('Zhang San', 'HuaWei')
sanJing = Japanese('San Jing', 'Basketball')
mimi = Cat('MIMI', 'fish')
objects = [zhangSan, sanJing, mimi]
for object in objects:
callLove(object)
程序输出:
Zhang San is Chinese, he love working
San Jing is Japanese, he love playing
MIMI is Cat, he love eating fish
复制代码
注意:
Chinese和Japanese有共同的祖先Person,而Cat和Chinese、Japanese完全不相关
三者都有共同的接口:love函数
callLove函数的参数是无类型的,实现以上功能,无须像Java一样要引入interface的概念
5、多继承
class Mix(Chinese, Japanese):
def __init__(self, cname, jname, company, interesting):
Chinese.__init__(self, cname, company)
Japanese.__init__(self, jname, interesting)
mix = Mix('Zhang San', 'San Jing', 'HuaWei', 'Basketball')
mix.love()
mix.work()
mix.play()
程序输出:
San Jing is Chinese, he love working
San Jing is working in HuaWei
San Jing is playing Basketball
复制代码
这是一个所谓的菱形继承,但是Mix类中只有一份name的拷贝
Mix的构造函数中,先调用Chinese的构造函数,把name初始化为Zhang San;随后调用Japanese的构造函数,把name有改为San Jing,因此后面打印出来的名字都是San Jing
work是Chinese特有的方法,调用正常
play是Japanese特有的方法,调用正常
love是Chinese和Japanese共有的方法,这里调用的是Chinese的love方法
6、模板
Python是动态类型的语言,天生支持模板,看两个例子:
函数模板
def min(a, b):
if (a < b):
return a
else:
return b
print(min(1, 2))
print(min(1.5, 2.5))
复制代码
类模板
objects = [Person('person'), Cat('mimi')]
复制代码
Python中内置的高级数据类型有:列表、字典、元组,它们可以存储任意类型的元素,实现容器时无须像C++的stl需要template的支持,这一点与Java类似。
[
本帖最后由 missjiang 于 2007-9-25 19:34 编辑
]
作者:
missjiang
时间:
2007-09-25 12:34
9、面向对象编程:异常处理
捕获除以零的异常
try:
a = 1
b = 0
c = a / b
print 'Never reach this line'
except ZeroDivisionError:
print 'Attempt divide by zero'
复制代码
定义自己的异常
class MyException(Exception):
def __init__(self, divisor, dividend):
self.divisor = divisor
self.dividend = dividend
def divide(divisor, dividend):
if divisor == 2 * dividend:
raise MyException(divisor, dividend)
print '%d / %d = %d' % (divisor, dividend, divisor / dividend)
try:
divide(9, 3)
divide(16, 4)
divide(4, 2)
except MyException, x:
print 'MyException is raised while execute divide(%d, %d)' % (x.divisor, x.dividend)
复制代码
finally子句
def openFile():
try:
print 'Open File'
file = open('/etc/passwd')
c = 1 / 0
finally:
print 'Close File'
file.close()
print 'Never reach this line'
try:
openFile()
except:
print 'Error occured while open file'
复制代码
作者:
jcodeer
时间:
2007-09-25 17:28
不错~~~~~
学习
作者:
szhaitao
时间:
2007-09-30 11:12
不错。。。。。。。看《简明 Python 教程》
Swaroop, C. H. 著
沈洁元 译
www.byteofpython.info
居然一直没找到怎么注释代码。。。。。。还是这样的笔记型的好,想读者所想,记读者易混淆
对于缩进代替结束关键字,感觉非常不爽
如果说为了强制代码规范,那为什么变量可以不定义就使用,而且可以随时改变其类型!这样只会更混乱。
——比较喜欢c++的随时随地{ }一个代码块里定义局部变量,对于pascal的函数头部统一声明变量也觉得太极端了
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2