Python学习笔记
------------------从2014-8-1号开始重新学习Python的笔记------------------
是学习vamei的Python快速教程的笔记。
1、关于变量
在Python中,变量不需要声明,可以直接使用。
2、序列(Squence)是一种有序元素的组合
有:tuple(定值表,或称为元组,用圆括号表示)、list(表,用方括号表示)。tuple的值不可以变,list的值可以变。
3、一个新的函数,range()可以用来帮助建立表list,实现循环的时候会经常用到。
for循环使用的格式是:
for 元素 in 序列: statement
序列可以是tuple,也可以是list,而且list可以用range()来创建。
while就比较简单了:
while 条件: statement
4、Python下面也有值传递(不会影响传递变量的值,他会在函数内部重新产生一个变量)&指针传递(会改变传递变量的值)
值传递发生在传递的是基本数据类型的变量,像是整形啊什么的。
指针传递发生在将一个表list传递给一个函数,对于表来说,表传递给函数的是一个指针,指针指向序列在内存中的位置,在函数中对表的操作将在原有内存中进行,从而影响原有变量。
附加,定义一个函数的格式为
def functionname(参数): statement return something #return is not necessary
记住:一个函数是一个对象
5、Python中的面向对象
Python的类有属性(attribute)&方法(method)。方法的第一个参数是self,因为我们需要用self来调用这个类的属性。
特殊方法:特殊方法名字前后都有两个下划线。如__init__(),在初始化的时候都会调用这个函数,在建立对象时自动执行。
class Human(object): def __init__(self, input_gender): self.gender = input_gender def printGender(self): print self.gender li_lei = Human('male') # 这里,'male'作为参数传递给__init__()方法的input_gender变量。 print li_lei.gender li_lei.printGender()
__init__()把属性Human.gender的不确定表现的很好,让我们自己来设定。NOTE:跟构造有同样的作用。
6、自学Python很重要的两个命令
dir()用来查询一个类或者对象的属性。help()用来查询说明文档。
注意:要明确Everything is Object!像我们用到的list、int都是一个类。
7、一个新的类:dictionary字典,它分为键和值,注意,词典的元素没有顺序,不能通过下标引用元素,而是用键来引用。。ex: dic={'tom':11,'sam':57,'lily':34}
容器(Container),可以存储多个元素的对象叫做容器。圆括号是tuple,中括号是list,大括号是dictionary。
注意,字典的常用方法:dictionary.keys(),获取所有键;dictionary.values(),获取所有值;dictionary.items(),所有元素,也就是键值对;dictionary.clear(),清空。 dic是一个对象,dic(键)就是代表相应的值。
8、文件操作
打开文件:
f=open(文件名,模式) #模式有“r”,只读;“w”,写入
操作:
content=f.read(N) #读取N bytes的数据 content=f.readline() #读取一行 content=f.readlines() #读取所有行,存储在列表中,每个元素是一行 f.write('I love U')
关闭文件:
f.close()
我们用print dir(file) 可以打印出更多的属性和方法。像是writelines()啊什么的都可以看见了。
9、模块(module):一个.py文件就是一个模块。
在一个模块中引入另一个模块a,这样写 import a
引入模块后,可以通过模块.对象的方式来调用引入模块中的某个对象(也可以用这种格式调用其中的函数,因为函数就是一个对象)。
其他的引入方式:
import a as b 将名字a重命名为b
from a import function1 引用a.function1,但是不用前面那么男写了,直接写function1就ok啦
from a import * 你懂的,跟上面的很像嘛
import搜索包的路径有:文件所在文件夹,标准库安装路径,操作系统环境变量PYTHONPATH所包涵的路径。
模块包,将功能相似的模块房子啊同一个文件夹(比如说this_dir)中,构成一个模块包,通过 import this_dir.module 引入文件夹中的module模块。文件夹中必须要包含一个__init__.py,提醒Python,该文件为一个模块包,__init__.py可以是一个空文件。
10、函数的参数
默认参数的设置
def f(a,b,c=10): return a+b+c print(f(3,2)) print(f(3,2,5)) #这样就对了,这样的话c就不是默认的10,c的值是5
包裹传递
在定义函数的时候,我们不知道要调用的时候会传递多少个参数。这时候,包裹(Packing)位置参数,或者包裹关键字参数,来进行参数传递,it works。
def func(*name):
在func参数表中,所有的参数被name收集,根据位置合并成一个元组(tuple)。为了提醒Python参数,name是包裹位置传递所用的元组名,在定义func时,在name前加*号。
def func(**dict):
合并成一个字典(dictionary)。要在前面加**
*和**,也可以在调用的时候使用,即解包裹(unpacking)。
11、几个可以使循环更加灵活的函数
first one: range()
second one: enumerate(),每次循环可以同时得到下标和元素。
third one: zip(),有多个等长的序列,然后想要每次循环时从各个序列分别取出一个元素,用它。每次循环,在list从左至右取出一个数组成一个tuple,所有的tuple合并成一个list:
ta=[1,2,3] tb=[7,8,9] #cluster 聚合 zipped=zip(ta,tb) print(zipped) #decompose 解聚合 na,nb=zip(*zipped) print(na.nb)
上面这个例子就很吊啦。注意decompose之后是几个tuple,而不是list。
12、循环对象
iteration [计算机]循环,迭代
一、迭代器iter()
生成器(generator)的主要目的就是构成一个用户自定义的循环对象。generator的编写方法和函数定义类似,只是在return的地方改为yield。它可以有多个yield,当生成器遇到一个yield的时候会暂停运行生成器,返回yield后面的值,当再次调用生成器的时候会从刚才暂停的地方继续运行,知道下一个yield。
二、生成器表达式(generator expression)。generator expression是生成器的一种简便的编写方式。
一个生成器:
def gen(): for i in range(4): yield i
可以写成generator expression:
G=(x for x in range(4))
三、表推导(list comprehension)是快速生成表的方法。语法简单,很有实用价值。
L=[] for x in range(10): L.append(x**2)
生成一个表。也可以用表推导的方式:
L=[x**2 for x in range(10)]
表推导与生成器表达式类似,只不过generator expression用的是小括号,表推导list comperhension用的是中括号。
13、函数对象
函数也可以作为一个对象进行参数传递,当然函数也可以作为一个对象作为return的结果。函数一个简写的方法,lambda表达式。
def func(x,y): return x+y #which can be express as follows func=lambda x,y:x+y
map()函数
re=map((lambda x:x+3),[1,2,4,6])
map()的功能是将后面list中数值依次带入前面的函数中,得到的结果依次放在re表中。
filter()函数
filter()第一个参数为一个函数,第二个对象是一个列表list,将list中的数依次放入到函数中运算,返回的是True则将这儿数放到结果的list中,要是返回的是False,则这个数就被过滤掉了。
reduce()函数
print reduce((lambda x,y:x+y),[1,3,4,5,7,9])
上面的例子相当于((((1+3)+4)+5)+7)+9
reduce()函数在3.0里面不能直接用的,它被定义在了functools包里面,需要引入包。
14、上下文管理器(Context Manager)
规定某个对象的使用范围。一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存,只是比如,并不是所有的离开了context就是释放了内存空间对象回收了)。它的语法形式是with ..EXPRESS.. as ..VAR..
任何定义了__enter__()和__exit__()方法的对象都可以用于上下文管理器。
实际上,任何一个有__call__()特殊方法的对象都被当作是函数。
15、属性attribute
有类属性(class attribute)和对象属性(object attribute)。对象属性存储在对象的__dict__属性中,__dict__是一个词典,键为属性名,值为属性本身。
在不知道一个对象用的是什么类的时候,用__class__属性可以找到对象的类,用类的__base__属性来查询父类。
特性(porperty)。一个对象的属性可能依赖另一个属性,当一个属性修改的时依赖他的属性也会相应改变。这是Python就需要一种特殊的机制来即时生成属性,这就是特性。特性使用内置函数property()来创建。前三个参数为函数,分别用于处理查询特性、修改特性、删除特性。最后一个参数为特性的文档,可以为一个字符串,起说明作用。
__getattr__(),他是一个特殊的方法,用来获得即时的生成的属性。我们用__dict__无法找到即时的属性,通过__getattr__()就可以获得该属性。
Python中还有一个__getattribute__特殊方法,用于查询任意属性。__getattr__只能用来查询不在__dict__系统中的属性
16、闭包(closure)
closure之于函数式编程,就像函数之于面向过程编程,class之于面向对象编程。
闭包(closure):一个函数和它的环境变量一起组成了一个闭包。环境变量取值被保存在函数对象的__closure__属性中。
def line_conf(a, b): def line(x): return ax + b return line line1 = line_conf(1, 1) line2 = line_conf(4, 5) print(line1(5), line2(5))
上面就是闭包的一个很好的例子。利用line1和line2创建了两个函数x+1,4x+5,并将它们返回,在print中有可以利用它们。这样就利用闭包创建了泛函。有效的减少了要定义函数的数目,减少了函数所需要定义的参数的数目。
17、装饰器(decorator)
def decorator(F): def new_F(a, b): print("input", a, b) return F(a, b) return new_F # get square sum @decorator def square_sum(a, b): return a**2 + b**2 # get square diff @decorator def square_diff(a, b): return a**2 - b**2 print(square_sum(3, 4)) print(square_diff(3, 4))
看上面的例子,我们可以很明显的发现,decorator就是将函数当做一个对象传递进来再将处理好的函数输出出去。被@了的函数就换掉了。
装饰器接受一个函数,并返回一个函数,从而起到加工函数的效果。
扩展一下:接受一个类,处理之后返回一个类,就达到了加工类的效果。这就是装饰类。
18、标准库(standard library)
forgive me,我已经迫不及待要进行标准库以及网络和服务器的搭建学习,基于Python。
Python的强大得益于它丰富的模块。
标准库:标准库会随着Python解释器,一起安装在你的电脑中的。它是Python的一个组成部分。这些标准库是Python为你准备好的利器,可以让编程事半功倍。
正则表达式(re,regular expression)注意之前混淆的 .任意一个字符 *重复>=0次 +重复>=1次 ?重复0次或1次
时间包有time包和datetime包
os.path包主要是处理路径字符串(这个包一部分类似于Linux中的ls命令)。
文件管理有(os部分,shutil包)
存储对象管理。我们在将内存中的数据转化成文本流(这个过程叫做serialize),然后将文本流存到文件中。由于有些对象的类使我们自己定义的,所以serialize的时候我们需要知道类的格式才是存储。所以我们需要用Python中的pickle包。还有就是cPickle,用法与pickle一样。可以用 import cPickle as pickle 然后就将cPickle当做pickle一样用就好了。
pickle.dumps() #serialize object pickle.dump()#serialize and save object
pickle.load()#read file and build object
执行外部命令和程序用subprocess包,从这个意义上来说,subprocess的功能与shell类似。这个简直是太棒了!
在Python下利用subprocess调用shell命令
除了subprocess.call()之外还有subprocess.check_call()、subprocess.check_output(),他们的用法几乎相同。实际上他们的用法都是基于Popen()的封装(wrapped)。
import subprocess child = subprocess.Popen(["ping","-c","5","www.google.com"]) child.wait() print("parent process")
要是没有child.wait()的话,就不一定先执行ping了,他会先执行print。
另外还有:
child.poll() # 检查子进程状态 child.kill() # 终止子进程 child.send_signal() # 向子进程发送信号 child.terminate() # 终止子进程
subprocess.PIPE的用法
import subprocess child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE) child2 = subprocess.Popen(["wc"], stdin=child1.stdout,stdout=subprocess.PIPE) out = child2.communicate() print(out)
subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
Popen.wait(), Popen.communicate()
信号包signal。用signal.signal(signalnum, handler)来预设信号处理函数。一个有用的函数是signal.alarm(),它被用于在一定时间之后,向进程自身发送SIGALRM信号。
补充几个信号:
SIGINT 当键盘按下CTRL+C从shell中发出信号,信号被传递给shell中前台运行的进程,对应该信号的默认操作是中断(INTERRUPT) 该进程。
SIGQUIT 当键盘按下CTRL+\从shell中发出信号,信号被传递给shell中前台运行的进程,对应该信号的默认操作是退出 (QUIT) 该进程。
SIGTSTP 当键盘按下CTRL+Z从shell中发出信号,信号被传递给shell中前台运行的进程,对应该信号的默认操作是暂停 (STOP) 该进程。
SIGCONT 用于通知暂停的进程继续。
SIGALRM 起到定时器的作用,通常是程序在一定的时间之后才生成该信号。
实现多线程用threading包。
19、网络编程
在Python中,我们利用socket包来进行网络编程。然而,socket传输自由度太高,从而带来很多安全和兼容的问题。我们往往利用高一些应用层协议来规定socket使用规则。以及所传输信息的格式。
我们还可以用SocketServer包来方便的架设服务器。
20.Django网络架构
要完成一个完美的服务器,需要学习MySQL。我能不能继续学习MySQL!
------------------以下全是2014-8-1号之前的笔记----------------
1.变量是指向内存的地址,改变数据值的大小,是改变他的指向。所以我们不能通过给变量赋值改变内存中的值。
2.变量不需要指定变量的类型:因为他们都是指向某一块数据类型单元,他们的类型是一样的,不要指定什么类型
3.在linux中安装第三方函数库很简单:easy_install httplib2
4.python的函数库主要包括:系统函数库、网上的第三方函数库、自己写的函数
5.Type(a) 输出变量a的类型
6.序列(Sequence)有两种:tuple(定值表; 也有翻译为元组) 和 list (表)。
一旦建立,tuple的各个元素不可再变更,而list的各个元素可以再变更。
7.字符串是一种特殊的元组!!!!
×8.乘方运算,比如3的2次方写成: 3**2
9.if elif else
10.range()可以用来建立表
11.函数的定义以def作为标记
12.None是Python中特殊的字符,表示什么也没有
13.基本数据类型的参数:值传递; 表作为参数:指针传递
14.在class中定义一个方法用def(跟函数的定义是一样的),方法的第一个参数必须是self,不管是不是用得到。
15.Python中的继承,是直接卸载类名后面的括号中的,要是没有父类就写object
16.在第14条中说到,方法的第一个参数必须是self,为什么?通过self,调用类的其他属性。
17.__init__()是一个特殊方法(special method)。Python有一些特殊方法。Python会特殊的对待它们。特殊方法的特点是名字前后有两个下划线。
如果你在类中定义了__init__()这个方法,创建对象时,Python会自动调用这个方法。这个过程也叫初始化。
18.__init__()是初始化,不是什么构造函数。__init__(): 在建立对象时自动执行.
19.dir()用来查询一个类或者对象所有属性; help()用来查询说明文档。
20.词典(dictionary)与列表相似,可以存储多个元素。这种存储多个元素的对象成为容器(container)。
21.在Python中,一个.py文件就构成一个模块。通过模块,你可以调用其它文件中的程序。引入模块用import
22.可以将功能相似的模块放在同一个文件夹(比如说this_dir)中,构成一个模块包。该文件夹中必须包含一个__init__.py的文件,提醒Python,该文件夹为一个模块包。__init__.py可以是一个空文件。
23.函数的参数传递可以有关键字传递。
24.关键字(keyword)传递是根据每个参数的名字传递参数。
25.包裹传递(Packing).在定义函数时,我们有时候并不知道调用的时候会传递多少个参数。这时候,包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递.
包裹传递的关键在于定义函数时,在相应元组(tuple)或字典(dict)前加*或**。
26.*和**,也可以在调用的时候使用,即解包裹(unpacking).
27.用range()来控制for循环
28.利用enumerate()函数,可以在每次循环中同时得到下标和元素。
29.如果有多个等长的序列,然后想要每次循环时从各个序列分别取出一个元素,可以利用zip()方便地实现。zip()函数的功能,就是从多个列表中,依次各取出一个元素。每次取出的(来自不同列表的)元素合成一个元组,合并成的元组放入zip()返回的列表中。zip()函数起到了聚合列表的功能。
30.当一个循环结构(比如for)调用循环对象时,它就会每次循环的时候调用next()方法,直到StopIteration出现,for循环接收到,就知道循环已经结束,停止调用next()。
31.生成器(generator)的主要目的是构成一个用户自定义的循环对象。
生成器的编写方法和函数定义类似,只是在return的地方改为yield。生成器中可以有多个yield。当生成器遇到一个yield时,会暂停运行生成器,返回yield后面的值。当再次调用生成器的时候,会从刚才暂停的地方继续运行,直到下一个yield。生成器自身又构成一个循环器,每次循环使用一个yield返回的值。
32.生成器表达式 (GeneratorExpression)
33.表推导(list comprehension)是快速生成表的方法.
Ex:L = [x**2 for x in range(10)]
34.Python中函数也是一个对象
35.lambda函数
36.函数可以作为一个对象,进行参数传递。
37.map()是Python的内置函数。map()的功能是将函数对象依次作用于表的每一个元素,他返回的是一个表(list)。
38.filter().filter函数的第一个参数也是一个函数对象。它也是将作为参数的函数对象作用于多个元素。如果函数对象返回的是True,则该次的元素被储存于返回的表中(NOTE:说明在函数中要是返回的是True或者False,但是filter返回的是list中的数,而不是True或者False)。filter通过读入的函数来筛选数据。同样,在Python 3.X中,filter返回的不是表,而是循环对象。
39.reduce函数的第一个参数也是函数,但有一个要求,就是这个函数自身能接收两个参数。reduce可以累进地将函数作用于各个参数。reduce()函数在3.0里面不能直接用的,它被定义在了functools包里面,需要引入包。
40.在我们接触的对象中,有一类特殊的对象,是用于存储数据的。常见的该类对象包括各种数字,字符串,表,词典。在C语言中,我们称这样一些数据结构为变量。而在Python中,这些是对象。
41.对象是储存在内存中的实体。但我们并不能直接接触到该对象。我们在程序中写的对象名,只是指向这一对象的引用(reference)。
42.引用和对象分离,是动态类型的核心。
43.关于对象动态类型的讨论→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→→ mutable object & immutable object
列表可以通过引用其元素,改变对象自身(in-place change)。这种对象类型,称为可变数据对象(mutable object),词典也是这样的数据类型。
而像之前的数字和字符串,不能改变对象本身,只能改变引用的指向,称为不可变数据对象(immutable object)。
我们之前学的元组(tuple),尽管可以调用引用元素,但不可以赋值,因此不能改变对象自身,所以也算是immutable object.
44.函数的参数传递,本质上传递的是引用。
45.immutable对象和mutable对象在传递时的不同
如果参数是不可变(immutable)的对象,a和x引用之间相互独立。对参数x的操作不会影响引用a。这样的传递类似于C语言中的值传递。
如果传递的是可变(mutable)的对象,那么改变函数参数,有可能改变原对象。
46.但是Python也提供更加简洁的语法,让你使用不同的编程形态,从而在必要时隐藏一些面向对象的接口。
EX:在连接字符串的时候'abc'+'def',实际上是利用了字符串'abc'对象的方法.__add__() 所以实际执行的操作是'abc'.__add__('def')
47.上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围。一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存)。它的语法形式是with...as...
NOTE:很像C#中的using语句
48.Python中变量名和对象是分离的。变量名可以指向任何一个对象。
49.装饰器(decorator)接收一个函数/类,返回一个函数/类。
从本质上,装饰器起到的就是一个重新指向变量名的作用(name binding),让同一个变量名指向一个新返回的可调用对象,从而达到修改可调用对象的目的。
50.为了探索对象在内存的存储,我们可以求助于Python的内置函数id()。它用于返回对象的身份(identity)。其实,这里所谓的身份,就是该对象的内存地址。
51.is用于判断两个引用所指的对象是否相同。
52.Python的一个容器对象(container),比如表、词典等,可以包含多个对象。实际上,容器对象中包含的并不是元素对象本身,是指向各个元素对象的引用。
53.Python中内置的对字符串进行格式化的操作%
54.IndentationError: unexpected indent错误
提示格式不对,检查缩进等等可能出现的错误
55.程序包(Package)
56.pip
A tool for installing and managing Python packages.
在https://pypi.python.org/pypi/pip中可下载
57.在Python里面任何非0的数也会被解释为'True'
58.pass
pass表示什么也不做,pass
59.在Python3中,即使是整数相除,除法也会进行浮点数除法。
60.Python可是一个文件管理的利器
61.关于文本流与serialize
计算机的内存中存储的是二进制的序列 (当然,在Linux眼中,是文本流)。我们可以直接将某个对象所对应位置的数据抓取下来,转换成文本流 (这个过程叫做serialize),然后将文本流存入到文件中。
-------------------------------语法(Syntax)------------------------------------------
1.import re
添加正则表达式的包
2.用from导入模块
如 from math import pi,现在就可以直接用pi了。要是没有前面的from,直接写import math,在用pi的时候须写成 math.pi
3.Python2提供了一个内置函数raw_input来从键盘获取输入。在Python3里,这个函数是input
4.time包
5.datetime包是基于time包的一个高级包, 为我们提供了多一层的便利。datetime可以理解为date和time两个组成部分。date是指年月日构成的日期(相当于日历),time是指时分秒微秒构成的一天24小时中的具体时间(相当于手表)
6.os.path 包主要是处理路径字符串。os.path还可以查询文件的相关信息(metadata)。实际上,这一部分,类似于Linux中的ls命令的某些功能。
7.glob包最常用的方法只有一个, glob.glob()。该方法的功能与Linux中的ls相似
8.os包包括各种各样的函数,以实现操作系统的许多功能。这个包非常庞杂。os包的一些命令就是用于文件管理。
9.cwd(current working directory,当前工作路径)
10.pickele和cPickle可以将:内存中的对象转换成文本流;重建对象
11.subprocess包主要功能是执行外部的命令和程序,从这个意义上来说,subprocess的功能与shell类似。subprocess可以创建子进程,另外它还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。
12.用subprocess.Popen()创建子进程,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待(也就是阻塞block)
13.可以利用subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe).subprocess.PIPE实际上为文本流提供一个缓存区。
14.通过使用subprocess包,我们可以运行外部程序。这极大的拓展了Python的功能。
15.signal信号
要注意,signal包主要是针对UNIX平台(比如Linux, MAC OS),而Windows内核中由于对信号机制的支持不充分,所以在Windows上的Python不能发挥信号系统的功能。
16.signal包的核心是使用signal.signal()函数来预设(register)信号处理函数
17.socket包,用来进行底层的socket的编程