《简明Python 教程》学习笔记
最近想学python,网上下了《简明Python教程》和《Python编程:从入门到实践》这两本书,但是一直没看,不是没时间看,是自己太懒。十一回家的途中,在动车上闲来无事,于是就把这本书过了一遍。的确是非常简洁易懂的一本编程书。也许是有了C和C++的基础,一路看下来特别顺畅,或许这就是传说中的举一反三?
Python,我总感觉像是C++和matlab的一个结合体,只是在部分的语法形式上做了改进。不过Python语言以简洁为中心的原则的确是挺吸引人的,何况还是开源的,想想都炫酷。
这本书是按如下结构安排的,其实这也是所有编程语言的学习思路。
安装Python
书上介绍了Linux和Windows的安装方法。
我是按Windows系统装的,版本当然是选择最新的:(不过这本教程用的是Python2,Python3在一些小地方有了改进)
https://jingyan.baidu.com/article/e73e26c0bad76224acb6a766.html
后面的环境变量可以在安装的时候自动设置。
Hello World!
打开”Python IDLE”,有两种方式运行hello world!:
hello world!.py:
print('hello world!')
(Python2不加括号,但是Python3必须有括号。)
- 直接在命令行后面输入+Enter
- File->New File,编辑,Run Module
让我有一种在用Matlab的赶脚。。
怎么通过py程序名在命令行中运行程序啊?
语法知识
常量
- 数
Python有四种类型的数:整数,长整数,浮点数,复数 - 字符串
单引号(’ ‘)和双引号(” “)的使用完全相同,三引号(”’ ”’或”“” “”“)可以将一个字符串分多行书写。
What’s your name?的写法:
1.”What’s your name?”
2.’What\’s your name?’,使用转义字符
自然字符串?
变量
- 标识符的命名规则:与C相同
- 变量可以处理不同类型的值,前面提到的数和字符串就是两种基本的数据类型。
- 变量在使用时,不需要声明或定义数据类型,可以直接赋值,这点与Matlab类似。
对象
Python中用到的所有东西都称为对象。
逻辑行、物理行与缩进
尽量避免使用分号(;),一行一条语句;
缩进至关重要,选择一种缩进风格(tab或2/4*space),不要混着用,否则跨平台时会无法工作。
运算符与表达式
和C语言基本没有区别。
控制流
if语句
if A:
do something
elif B:
do somethingelse
else:
do other things
while…语句
#while是可以与else联合使用的
while A:
do something
else:
do other things
for…语句
#逐一调用序列中的每个项目
for i in range(1,10):
print(i)
else:
print("The Loop is over!")
break和continue:
break直接跳出当前循环;
continue跳过后续语句,直接进入下一次循环。
函数
函数就是可重用的程序段。分为内建函数(BIF)和自定义函数。
Python定义函数的格式如下:
def SayHello():
print("hello world!")
SayHello()#call the function
1. 形参和实参
2. 局部变量和全局变量:在函数体内定义global x,并改变其值,则函数体外的x的值也会发生改变。
def Change():
global x
x=100
x=1
print(x)
Change()
print(x)
>>>输出为:
1
100
3. 默认参数和关键参数
默认参数:在函数定义时,给形参赋一个初始值,作为默认值;
关键参数:特定的几个需要手动赋值的参数。关键参数赋值就是用名字赋值而非顺序赋值,这样避免了混乱。
def func(a,b=0,c=1):
print("a,b,c分别为:")
print(a,b,c)
func(100)
func(25,c=10)
func(c=50,a=30)
输出为:
100 0 1
25 0 10
30 0 50
- return
用来跳出函数或者从函数返回一个值。 Docstrings
用于输出函数的属性,和help(func)的功能一样。def PrintN(x):
”’This function will print a number.more details from here...''' print(int(x)) PrintN(100) print(PrintN.__doc__)
输出:
100
This function will print a number.more details from here…
模块
模块是指有很多你定义的函数和变量所组成的文件(.py),模块一般具有某一特定功能,并可以在不同程序中重复使用。
输入模块的方式:
import sys
form sys import argv(这样就不用每次调用都用sys.xxx,但可能会造成重名)使用sys模块(Python标准库模块)
import sys print("The command line arguement are:") for i in sys.argv: print(i) print("\n\nThe PYTHONPATH is",sys.path,"\n")
制造和使用自定义的模块
每个python程序就是一个模块。# Filename: mymodule.py def sayhi(): print("hi,this is mymodule speaking.") version="1.0" # End of mymdule.py
使用一个模块(注意要放在同一目录下):
# Use the module import mymodule mymodule.sayhi() print("Version",mymodule.version)
输出为:
hi, this is mymodule speaking.
Version 1.0
以下语句可以用来判断模块是单独运行还是被其他程序调用(使用模块的名称__name__):
if __name__=="__main__":
print("run by myself")
else:
print("run by others")
数据结构
数据结构是指用于存储和处理一组相关数据的结构,使用它们可以使编程更简单。
Python中有三种内建的数据结构——列表、元组和字典。
1. 列表
列表是处理一组有序项目的数据结构,这里的项目可以是任何种类的对象,如数,字符串,列表等。(类似于C语言中的结构体)
# Build a list
mylist=['apple','banana','mango','carrot']
# Use the list to do something
print('I have',len(mylist),'items to purchase,')
print('they\'re :')
for item in mylist:
print(item)
print('\nI also want to buy rice,')
mylist.append('rice')
print('now the list becomes:',mylist)
mylist.sort()
print('The sorted list:',mylist)
print('And I have gotten the first item ',mylist[0],'already.')
del mylist[0]
print('Now I get my new list:',mylist,'\nhaha')
2. 元组
元组与列表非常相似,唯一的不同是它和字符串一样是不可变的,即你不能修改一个元组。建立元组使用的是”()”,如zoo = (‘wolf’, ‘elephant’, ‘penguin’)。注意单个元素的元组的写法:one=(‘just me’,)。
元组最为常见的用法是在打印语句中:
#格式化打印
print('''When he was %d years old,\nhe thought himself as %s'''%(22,'the king of the world.'))
输出:
When he was 22 years old,
he thought himself as the king of the world.
字典
字典,就是字典。由许多键/值对组成,这些键值对是无序的。# This is a adrress book ab={'John Snow':'Winterfell','Arya Stark':'Winterfell', 'Cersei Lannister':'Casterly Rock', 'Deanerys Targaryen/Khaleesi': 'King\'s Land' } print("John Snow's hometown is %s."%ab['John Snow']) # Add a key/value pair ab['Tyrion Lannister']='Casterly Rock' # Del a key/value pair del ab['Cersei Lannister'] print('\nThere are %d characters in the book:\n'%len(ab)) for name,hometown in ab.items(): print('%s:%s\n'%(name,hometown))
序列
列表、元组、字符串都是序列。序列的两个特点是索引操作符和切片操作符。# Seq mylist=['apple','banana','carrot','milk','basketball'] # Indexing operation print('Item 0 is',mylist[0]) # Slicing operation print('Item 1 to 3 are:',mylist[1:3]) #切片在3号元素前面,所以不包括它 print('Item 1 to -1 are:',mylist[1:-1]) #-1表示最后一个元素 print('Item Start to End are:',mylist[:])
引用
把一个对象整体赋给一个变量时,变量只是引用了对象,就是说变量名指向对象的地址。# Filename: reference.py print 'Simple Assignment' shoplist = ['apple', 'mango', 'carrot', 'banana'] mylist = shoplist # mylist is just another name pointing to the same object! del shoplist[0] print 'shoplist is', shoplist print 'mylist is', mylist # notice that both shoplist and mylist both print the same list without # the 'apple' confirming that they point to the same object print 'Copy by making a full slice' mylist = shoplist[:] # make a copy by doing a full slice del mylist[0] # remove first item print 'shoplist is', shoplist print 'mylist is', mylist # notice that now the two lists are different
- 字符串
字符串也是对象,其中也包含很多方法,比如查找字符、添删空格都可以通过内置函数进行操作。(help(str))
解决问题——编写一个Python脚本
开发一个程序的思路:
- 提出问题:我想要一个能为我的所有重要文件创建备份的程序。
- 分析问题:如何实现(怎么知道要备份的文件?备份放在哪里?怎么存储备份?…)
- 解决方案:初始版本
- 不断优化:版本2,3,4,…
这里有一句话叫做:软件是长出来的,而不是建造出来的!
#Filename:backup_ver1.py
import os
import time
# 待备份文件
source=[r'E:\123.txt',r'E:\456.pdf']
# 目标文件夹
target_dir=r'E:\backup'
# 压缩文件名:这里为压缩时间
target=target_dir+'\\'+time.strftime('%Y%m%d%H%M%S')+'.rar'
# 利用压缩软件进行压缩处理
rar_command='"C:\Program Files\WinRAR\Rar.exe" a %s %s'%(target,' '.join(source))
#"C:\Program Files\WinRAR\Rar.exe"为压缩软件的安装路径
#后面的a不知道什么意思...
#target: 待创建的文件的名称
#‘ '.join(source) 待备份的文件和目录列表
# 判断是否备份成功
if os.system(rar_command)==0:
print('文件成功备份到',target,'!')
else:
print('备份失败!')
注意:教程上使用的是Linux自带的zip进行压缩,因为我用的windows系统,所以这里使用的是rar程序。最理想的方法是使用python标准库中的zipfile和tarfile函数。
#Filename:backup_ver2.py
# 1.对文件名进行了优化
# 2.添加说明信息的功能
import os
import time
# 待备份文件
source=[r'E:\123.txt',r'E:\456.pdf']
# 目标文件夹
target_dir=r'E:\backup'
# 压缩文件名
# 子目录为日期
today=target_dir+'\\'+time.strftime('%Y%m%d')
# 文件名为时间
now=time.strftime('%H%M%S')
# 输入说明信息
comment=input('Enter a comment -->')
if len(comment)==0:
target=today+os.sep+now+'.rar'
else:
target=today+os.sep+now+'_'+comment.replace(' ','_')+'.rar'
# 检查子目录是否存在,不存在则创建之
if not os.path.exists(today):
os.mkdir(today)
print('成功创建目录',today)
# 利用压缩软件进行压缩处理
rar_command='"C:\Program Files\WinRAR\Rar.exe" a %s %s'%(target,' '.join(source))
#"C:\Program Files\WinRAR\Rar.exe"为压缩软件的安装路径
#后面的a不知道什么意思...
#target: 待创建的文件的名称
#‘ '.join(source) 待备份的文件和目录列表
# 判断是否备份成功
if os.system(rar_command)==0:
print('文件成功备份到',target,'!')
else:
print('备份失败!')
面向对象的编程
终于来到面向对象的内容了!
- 类和对象的关系:与C相同
- 类或对象的属性:域(变量)+方法(函数)
- 类或对象的方法必须有一个特殊的参数self,用来指代类或对象本身
- __init__方法用于初始化,类似于C++中的构造函数
- 两种域:类的变量为所有对象所共享,在某个对象中改变它则在其他对象中也会得到反映;对象的变量则为其所独立拥有
# 创建一个类
class Person:
number=0
def __init__(self,name):
self.name=name
def Sayhi(self):
print('Hi,I am %s'%self.name)
# 创建和使用对象
No1=Person('Arya')
No1.Sayhi()
类的继承和多态:与C++类似。
子类的定义形式为:
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
高级一些的操作
文件的读写
1.使用open函数
# 使用文件类file进行读取,与C类似
poem='''一天很短,
短得来不及拥抱清晨,
就已经手握黄昏。
'''
f=open('poem.txt','w')
f.write(poem)
f.close()
f=open('poem.txt')
while True:
line=f.readline()
if len(line)==0:
break
print(line)
f.close
注:
教程上使用的是file类,但是python3中file显示为undefined,网上找了一下,都是用open实现的。
2. 使用标准模块pickle或cPickle进行快速存取
# pickle
import pickle as p
shoplistfile='shoplist.dat'
shoplist=['apple','banana','car']
f=open(shoplistfile,'wb')
p.dump(shoplist,f)
f.close()
del shoplist
f=open(shoplistfile,'rb')
storedlist=p.load(f)
print(storedlist)
注:实际编程时发现了两个问题:
1. wb和rb,即以二进制方式读写,不加b的话会弹出类型错误;
2.dump函数有三个参数,最后一个为序列化使用的协议版本号(?)。
异常处理
参考这篇博文:http://blog.youkuaiyun.com/yl2isoft/article/details/51884502
# try_except.py
import sys
# 用户自定义异常类
class DirtyWords(Exception):
def __init__(self,text):
self.text=text
try:
t=input('然后输入一个字符串吧:')
if t=='Fuck':
raise DirtyWords('Fuck!')
except EOFError:
print('发生了一个EOF错误!')
sys.exit()
except DirtyWords as x:
print('小孩子不要说脏话哦。%s'%x.text)
sys.exit()
except:
print('发生了其他错误!')
sys.exit()
print('老铁,没毛病!')
Python标准库
标准库=很多可以直接使用的模块都在这儿。
-sys模块:提供系统相关命令,如sys.version
-os模块:包含普遍的操作系统功能,如果希望程序与平台无关的话,这个模块尤为重要。如前面使用的os.sep可以取代操作系统特定的路径分割符。
可以利用Python标准文档来了解更多内容。
Python的更多内容
列表综合:
# 列表综合 list1=[1,2,3,4] list2=[2*i for i in list1 if i>1] print(list1) print(list2)
输出为:
[1,2,3,4]
[4,6,8]
这样做比使用循环更加精确、简洁。在函数中接收列表或元组作为参数
# 列表或元组作为函数参数 def powersum(power,*args): '''这个函数返回 元组args中元素的power次方和。 ''' total=0 for i in args: total+=pow(i,power) #pow为内置函数,计算i的power次方 return total p=powersum(2,1,2,3) #第一个参数为power的赋值 #所有多余的函数参数都会作为一个元组存储在args中。 #如果使用的是**前缀,多余的参数则会被认为是一个字典的键/值对 print(p)
lambda语句
被用来创建新的函数对象,并且在运行时返回它们。# lambda.py def make_repeater(n): return lambda s:s*n #lambda只需要一个参数,并以单个表达式作为函数体 #注意只能是表达式,print语句也不能使用 twice=make_repeater(2) #这里的相当于twice(s):s*2 print(twice('hello')) print(twice(5))
输出为:
hellohello
10
接下来学习什么
》》》实践:使用Python创建一个地址簿程序,具有添加、删除、修改、搜索联系人及他们信息的功能。这些信息应该能够内存储下来以供查询。
》》》选择一个Python的GUI库,进行图形软件的开发。
Windows:Tkinter、wxPython(推荐) 、Pyqt