免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7351 | 回复: 11
打印 上一主题 下一主题

Python的入门简介 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-09-25 12:28 |只看该作者 |倒序浏览
前段时间老板要做一个项目,采用的开发语言是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 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-09-25 12:29 |只看该作者
1、第一个Python脚本: hello world

  1. #!/usr/bin/python
  2. print 'hello world'
复制代码

与C语言的不同地方在于:
  • 不需要使用 ; 结尾
  • 不需要使用 () 把参数包起来
  • 可以使用单引号

这些做法可以使得程序看上去较为清爽,当然如果你不习惯的话,Python编译器也可以接受以下的风格

  1. #!/usr/bin/python
  2. print("hello world");
复制代码

论坛徽章:
0
3 [报告]
发表于 2007-09-25 12:29 |只看该作者
2、Python语言与传统的C++/Java语言显著不同的地方
  • 变量在使用之前无须声明

    1. a = 1
    2. b = "hello world"
    复制代码

  • 使用 # 而不是//和/* ... */注释代码

    1. c = a + b # this is comment
    复制代码

  • 表达式语句不需要使用 ; 结尾

    1. a = a + 1
    2. b = b + 1
    复制代码

  • 函数调用时不需要使用 () 把参数包起来,if/while 中的也不需要使用()把条件表达式包起来

    1. print "hello world"
    2. if a == b:
    3.         print 'a == b'
    4. else:
    5.         print 'a != b'
    复制代码

  • 引号有单引号、双引号、三引号三种形式,后面详述
  • 使用“缩进”而不是{}标志代码块,下面我们将详细讨论这样作的优缺点.

先看一个例子:

  1. a = 1
  2. b = 2
  3. c = 3
  4. d = 3
  5. if a == b:
  6.         if c == d:
  7.                 print 'a == b && c == d'
  8. else:
  9.         print 'a != b'
  10. # 程序运行结果:a != b
复制代码

注意:
  • 缩进相同的语句处于同一个语法块中
  • 在if/else语句末尾有一个冒号,代表语法块的开始
  • python中提供了pass语句,该条语句表示一个空操作

    1. a = 1
    2. b = 2
    3. if a == b:
    4.         pass
    5. else:
    6.         print 'a != b'        
    7. # 程序运行结果:a != b
    复制代码



Python语言这种做法的优点在于:
  • 省去{}或者begin/end,使得程序结构更为清晰(也许有人会有不同的观点):
  • 强制所有的Python程序都有着相同的风格,不会像在C语言中出现风格迥异的情况:

    1. /* K&R的风格 */
    2. if (a > b) {
    3.    printf("a > b")
    4. }

    5. /* 很多人喜欢的风格 */
    6. if (a > b)
    7. {
    8.    printf("a > b")
    9. }

    10. /* EMACS编辑器的风格 */
    11. if (a > b)
    12.   {
    13.    printf("a > b")
    14.   }
    复制代码

  • 避免了如下情况由于忘记{}而造成的错误

    1. #include <stdio.h>

    2. int main()
    3. {
    4.         int a, b, c, d;
    5.         a = 1;
    6.         b = 2;
    7.         c = 3;
    8.         d = 3;
    9.         if (a == b)
    10.                 if (c == d)
    11.                         puts("a == b && c == d");
    12.         else
    13.                 puts("a != b");
    14.         return 0;
    15. }
    复制代码

    从缩进来看,编写这段代码的程序员的本意是希望当a、b不相等时输出"a != b",但是程序运行时没有任何输出,和程序员期待的结果是不一样的。


Python语言这种做法的缺点在于:
  • python的代码一旦缩进乱了,无法重新格式化
  • 粘贴代码的时候,缩进会被破坏,不方便

这些缺点倒是可以接受,关键在于用户是否认同Python缩进的优点。

论坛徽章:
0
4 [报告]
发表于 2007-09-25 12:30 |只看该作者
3、Python语言的控制结构
  • if 语句

    1. a = 1
    2. b = 2
    3. if a < b:
    4.         print 'a < b'
    5. elif a == b:
    6.         print 'a == b'
    7. else:
    8.         print 'a > b'
    复制代码

    注意:Python中提供了elif语句,是else if的缩写。
  • switch 语句
    python没有提供switch 语句,另外python也不提供++、--运算符。
  • while 语句

    1. sum = 0
    2. i = 1
    3. while i < 101:
    4.         sum += i
    5.         i += 1
    6. else:
    7.         print("LOOP IS OVER, i = %d" % i)  # 格式化字符串输出的细节在后面详述
    8. print("sum = %d" % sum)
    复制代码

    程序运行结果:
    LOOP IS OVER, i = 101
    sum = 5050
  • while循环中的else语句
    while循环中有一个可选的else语句,当循环没有被break中断而结束时,执行else后面的语句块,如果把程序改为:

    1. sum = 0
    2. i = 1
    3. while i < 101:
    4.         sum += i
    5.         i += 1
    6.         break
    7. else:
    8.         print("LOOP IS OVER, i = %d" % i)
    9. print("sum = %d" % sum)
    复制代码

    程序运行结果变为:
    sum = 1
  • for 语句
    python中不提供C语言风格的for循环,如下代码段是不被接受的:

    1. for (i = 1; i < 101; i += 1):
    2.         sum += i
    复制代码


    要计算从1累加到100的和,通常使用如下方法:

    1. sum = 0
    2. for i in range(1, 101):
    3.         sum += i
    4. else:
    5.         print "LOOP IS OVER, i = %d" % i
    6. 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

    1. for i in range(10, 0, -1):
    2.         print i
    3. 程序输出结果:
    4. 10
    5. 9
    6. 8
    7. 7
    8. 6
    9. 5
    10. 4
    11. 3
    12. 2
    13. 1
    复制代码

    在这个例子中,start = 10,  end = 0,  step = -1,程序的功能类似于如下C代码:

    1. start = 10
    2. end = 0
    3. step = -1
    4. for (i = start; i > end; i += step)
    5.         print(i)
    复制代码

论坛徽章:
0
5 [报告]
发表于 2007-09-25 12:31 |只看该作者
4、变量声明和定义
  • 变量在使用之前无须声明

    1. var = 1
    2. print var
    复制代码

  • 变量在使用之前必须定义

    1. print var
    2. # 运行时刻出错,NameError: name 'var' is not defined
    复制代码

  • 定义变量时,可以获知变量的类型,需要记住列表、字典、元组使用不同的括号[]、{}、()

    1. # 整数
    2. integer = 123         

    3. # 字符串
    4. string = "hello"         

    5. # 列表
    6. list = [1, 2, 3]

    7. # 字典
    8. dict = {1:2, 2:4, 3:6}   

    9. # 元组
    10. tuple = (1, 2, 3)        
    复制代码

  • 在函数中缺省访问的是局部变量,当使用global声明后,访问的才是全局变量

    1. def func():
    2.         g = 2  # 局部变量

    3. g = 1
    4. func()
    5. print(g)
    复制代码

    func中修改了局部变量g,没有影响全局变量g,输出结果为1


    1. def func():
    2.         global g
    3.         g = 2  # 全局变量

    4. g = 1
    5. func()
    6. print(g)
    复制代码

    func中修改了全局变量g,输出结果为2

论坛徽章:
0
6 [报告]
发表于 2007-09-25 12:31 |只看该作者
5、函数
  • 使用def定义函数

    1. def add(a, b):
    2.        return a + b

    3. print(add(1, 2))
    复制代码

    运行结果为3
  • 函数可以递归调用

    1. def fact(n):
    2.         if n == 0:
    3.                 return 1
    4.         else:
    5.                 return n * fact(n - 1)
    6. print(fact(3))
    复制代码

    运行结果为6
  • 缺省参数

    1. def func(a = 'a', b = 'b', c = 'c', d = 'd', e = 'e', f = 'f'):
    2.         print a + b + c + d + e + f
    3. # 情况1:所有参数使用缺省值
    4. # 输出结果:abcdef
    5. func()

    6. # 情况2:前面的参数使用指定值,后面的参数使用缺省值
    7. # 输出结果:ABCdef
    8. func('A', 'B', 'C')

    9. # 情况3:任意指定哪些参数接受缺省值,哪些参数使用指定值
    10. # 输出结果:aBcDeF
    11. func(b = 'B', d = 'D', f = 'F')
    复制代码

  • 把所有的参数存放在数组中

    1. add函数把接受的参数相加,并把和打印出来,注意args前面有一个*
    2. def add(*args):
    3.         sum = 0
    4.         for i in args:  # 遍历数组
    5.                 sum += i
    6.         print sum

    7. # 情况1:所有参数使用缺省值
    8. # 输出结果:abcdef
    9. func()

    10. # 情况2:前面的参数使用指定值,后面的参数使用缺省值
    11. # 输出结果:ABCdef
    12. func('A', 'B', 'C')

    13. # 情况3:任意指定哪些参数接受缺省值,哪些参数使用指定值
    14. # 输出结果:aBcDeF
    15. func(b = 'B', d = 'D', f = 'F')
    复制代码

  • 使用lambda生成一个新的函数

    1. def generate_multiplier(factor):
    2.         return lambda x: x * factor

    3. # 生成一个功能为乘以2的函数mul2,输出结果为200,mul2的定义相当于:
    4. # def mul2(x):
    5. #         return x * 2
    6. mul2 = generate_multiplier(2)
    7. print(mul2(100))

    8. # 生成一个功能为乘以4的函数mul4,输出结果为400,mul4的定义相当于:
    9. # def mul4(x):
    10. #         return x * 4
    11. mul4 = generate_multiplier(4)
    12. print(mul4(100))

    13. # 生成一个功能为乘以8的函数mul8,输出结果为800,mul8的定义相当于:
    14. # def mul8(x):
    15. #         return x * 8
    16. mul8 = generate_multiplier(8)
    17. print(mul8(100))
    复制代码

论坛徽章:
0
7 [报告]
发表于 2007-09-25 12:32 |只看该作者
6、列表、字典、元组
待续...

论坛徽章:
0
8 [报告]
发表于 2007-09-25 12:32 |只看该作者
7、字符串处理
待续...

论坛徽章:
0
9 [报告]
发表于 2007-09-25 12:33 |只看该作者
8、面向对象编程:封装、继承、虚拟函数、接口、多继承、模板
Python是一种典型的动态类型语言,由于他的动态性:
  • 天生支持虚拟函数、接口、模板等特征,无须引入特定的关键字
  • 在多继承中不存在“菱形继承”引发的问题

下面我们通过举例的方式学习面向对象语言中的各种特性

1、封装

  1. class Person:
  2.         def __init__(self, name):
  3.                 self.name = name
  4.         def getName(self):
  5.                 return self.name

  6. person = Person('person')
  7. print 'name = %s' % person.getName()

  8. 程序输出:
  9. name = person
复制代码

与C++不同的地方:
  • 类的成员函数的第一个参数是指向这个对象的self引用
  • 在成员函数里,必须通过self引用访问其他的成员变量或者成员函数

    1. class Person:
    2.         def __init__(self, name):
    3.                 self.name = name
    4.                 getName()
    5.         def getName(self):
    6.                 return self.name

    7. person = Person('person')
    8. print 'name = %s' % person.getName()

    9. 运行时刻出错,NameError: global name 'getName' is not defined
    复制代码

  • 构造函数的名称为__init__


2、继承

  1. class Chinese(Person):
  2.         def __init__(self, name, company):
  3.                 Person.__init__(self, name)
  4.                 self.company = company
  5.         def love(self):
  6.                 print '%s is Chinese, he love working' % self.name
  7.         def work(self):
  8.                 print '%s is working in %s' % (self.name, self.company)

  9. class Japanese(Person):
  10.         def __init__(self, name, interesting):
  11.                 Person.__init__(self, name)
  12.                 self.interesting = interesting
  13.         def love(self):
  14.                 print '%s is Japanese, he love playing' % self.name
  15.         def play(self):
  16.                 print '%s is playing %s' % (self.name, self.interesting)

  17. zhangSan = Chinese('Zhang San', 'HuaWei')
  18. zhangSan.love()
  19. zhangSan.work()

  20. sanJing = Japanese('San Jing', 'Basketball')
  21. sanJing.love()
  22. sanJing.play()

  23. 程序输出:
  24. Zhang San is Chinese, he love working
  25. Zhang San is working in HuaWei
  26. San Jing is Japanese, he love playing
  27. San Jing is playing Basketball
复制代码


3、虚拟函数

  1. zhangSan = Chinese('Zhang San', 'Hua Wei')
  2. sanJing = Japanese('San Jing', 'Basketball')

  3. persons = [zhangSan, sanJing]
  4. for person in persons:
  5.         person.love()

  6. 程序输出:
  7. Zhang San is Chinese, he love working
  8. 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、接口

  1. class Cat:
  2.         def __init__(self, name, food):
  3.                 self.name = name
  4.                 self.food = food
  5.         def love(self):
  6.                 print '%s is Cat, he love eating %s' % (self.name, self.food)

  7. def callLove(object):
  8.         object.love()

  9. zhangSan = Chinese('Zhang San', 'HuaWei')
  10. sanJing = Japanese('San Jing', 'Basketball')
  11. mimi = Cat('MIMI', 'fish')
  12. objects = [zhangSan, sanJing, mimi]
  13. for object in objects:
  14.         callLove(object)

  15. 程序输出:
  16. Zhang San is Chinese, he love working
  17. San Jing is Japanese, he love playing
  18. MIMI is Cat, he love eating fish
复制代码

注意:
  • Chinese和Japanese有共同的祖先Person,而Cat和Chinese、Japanese完全不相关
  • 三者都有共同的接口:love函数
  • callLove函数的参数是无类型的,实现以上功能,无须像Java一样要引入interface的概念


5、多继承

  1. class Mix(Chinese, Japanese):
  2.         def __init__(self, cname, jname, company, interesting):
  3.                 Chinese.__init__(self, cname, company)
  4.                 Japanese.__init__(self, jname, interesting)

  5. mix = Mix('Zhang San', 'San Jing', 'HuaWei', 'Basketball')
  6. mix.love()
  7. mix.work()
  8. mix.play()

  9. 程序输出:
  10. San Jing is Chinese, he love working
  11. San Jing is working in HuaWei
  12. 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是动态类型的语言,天生支持模板,看两个例子:

函数模板

  1. def min(a, b):
  2.         if (a < b):
  3.                 return a
  4.         else:
  5.                 return b

  6. print(min(1, 2))
  7. print(min(1.5, 2.5))
复制代码


类模板

  1. objects = [Person('person'), Cat('mimi')]
复制代码

Python中内置的高级数据类型有:列表、字典、元组,它们可以存储任意类型的元素,实现容器时无须像C++的stl需要template的支持,这一点与Java类似。

[ 本帖最后由 missjiang 于 2007-9-25 19:34 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2007-09-25 12:34 |只看该作者
9、面向对象编程:异常处理

捕获除以零的异常

  1. try:
  2.         a = 1
  3.         b = 0
  4.         c = a / b
  5.         print 'Never reach this line'
  6. except ZeroDivisionError:
  7.         print 'Attempt divide by zero'
复制代码


定义自己的异常

  1. class MyException(Exception):
  2.         def __init__(self, divisor, dividend):
  3.                 self.divisor = divisor
  4.                 self.dividend = dividend

  5. def divide(divisor, dividend):
  6.         if divisor == 2 * dividend:
  7.                 raise MyException(divisor, dividend)
  8.         print '%d / %d = %d' % (divisor, dividend, divisor / dividend)

  9. try:
  10.         divide(9, 3)
  11.         divide(16, 4)
  12.         divide(4, 2)
  13. except MyException, x:
  14.         print 'MyException is raised while execute divide(%d, %d)' % (x.divisor, x.dividend)
复制代码


finally子句

  1. def openFile():
  2.         try:
  3.                 print 'Open File'
  4.                 file = open('/etc/passwd')
  5.                 c = 1 / 0
  6.         finally:
  7.                 print 'Close File'
  8.                 file.close()
  9.         print 'Never reach this line'

  10. try:
  11.         openFile()
  12. except:
  13.         print 'Error occured while open file'
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP