python学习笔记(一)
更新日期:
这个python记录的有点乱,都是在看电子档资料的时候,记录下来的。
1、学习Python与其他语言最大的区别就是,Python的代码块不使用大括号({})来控制类,函数以及其他逻辑判断。python最具特色的就是用缩进来写模块。
缩进的空白数量是可变的,但是所有代码块语句必须包含相同的缩进空白数量,这个必须严格执行
2、Python语句中一般以新行作为为语句的结束符。但是可以使用斜杠( \)将一行的语句分为多行显示,但是如果包含[], {} 或 () 括号就不需要使用多行连接符。
3、Python 接收单引号(‘ ),双引号(“ ),三引号(‘’’ “””) 来表示字符串,引号的开始与结束必须的相同类型的。其中三引号可以由多行组成,编写多行文本的快捷语法
4、注释采用#,还有一种文档字符串的特别注释。你可以在模块、类或者函数的起始添加一个字符串,起到在线文档的功能。与普通注释不同,文档字符串可以在运行时访问,也可 以用来自动生成文档。
5、Python中的变量不需要声明,变量的赋值操作既是变量声明和定义的过程。每个变量在内存中创建,都包括变量的标识,名称和数据这些信息。在使用前都必须赋值,变量赋值以后该变量才会被创建。
6、可以为多个对象指定多个变量:a, b, c = 1, 2, “john” 即将1赋给a,2赋给b,john赋给c。
7、Python有五个标准的数据类型:
Numbers(数字):int long(L) float complex
String(字符串):python的字串列表有2种取值顺序:从左到右索引默认0开始的,最大范围是字符串长度少1,从右到左索引默认-1开始的,最大范围是字符串开头。+是字符串连接运算符,星号()是重复操作(print str2输出两个str);[:]表示截取字符串的一部分
List(列表):list = [ ‘abcd’, 786 , 2.23, ‘john’, 70.2 ]列表可以完成大多数集合类的数据结构实现。它支持字符,数字,字符串甚至可以包含列表(所谓嵌套)。
Tuple(元组):用”()”标识。内部元素用逗号隔开。但是元素不能二次赋值(不能修改也不能删除),相当于只读列表,只有一个元素时要留有逗号a=(1,);可以使用del删除整个元祖
Dictionary(字典):用”{ }”标识,由索引(key)和它对应的值value组成。结构类似json
列表:是有序的对象结合,字典是无序的对象集合。两者之间的区别在于:字典当中的元素是通过键来存取的,而不是通过偏移存取。
python创建对象后,数据类型是不允许改变的,只能用del var1,var2来删除多个对象。
字典:字典值可以没有限制地取任何python对象,既可以是标准的对象,也可以是用户定义的,但键不行。不允许同一个键出现两次。创建时如果同一个键被赋值两次,后一个值会被记住,键必须不可变,可以用数,字符串或元组充当,但不可以用列表就不行,
python算术运算符
*:幂运算 2*3=8
//:取整数 返回商的整数部分 9.0//2.0=4.0
and:(a and b) 返回 true,类似的有or 和 not
in:成员运算符 x in y 如果x在y中,则为TRUE,not in 表示为x不在y中怎为TRUE
is:身份运算符is是判断两个标识符是不是引用自一个对象(返回结果 1),is not是判断两个标识符是不是引用自不同对象
python流程控制
1、if 判断条件:
执行语句……
else:(elif 判断条件:)
执行语句……
python 并不支持 switch 语句,所以多个条件判断,只能用 elif 来实现,如果判断需要多个条件需同时判断时,可以使用 or 或and
2、while 判断条件:
执行语句……
else:
在 python 中,for … else 表示这样的意思,for 中的语句和普通的没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行,while … else 也是一样。while 可以循环嵌套
3、for itareting_var in sequence
statement(s)
Python函数
函数代码块以def关键词开头,后接函数标识符名称和圆括号()。
任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
函数内容以冒号起始,并且缩进。
Return[expression]结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
定义一个什么事也不做的空函数,可以用pass语句
函数返回多值,其实就是一个tuple:x,y=myfun() == r=myfun(),r=(x,y)
def functionname( parameters ):
"函数_文档字符串"
function_suite
return [expression]
所有参数(自变量)在Python里都是按引用传递。如果你在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。
默认参数:
先定义一个函数,传入一个list,添加一个END再返回:
def add_end(L=[]):
L.append('END')
return L
当你正常调用时,结果似乎不错:
\>>> add_end([1, 2, 3])
[1, 2, 3, ‘END’]
\>>> add_end([‘x’, ‘y’, ‘z’])
[‘x’, ‘y’, ‘z’, ‘END’]
当你使用默认参数调用时,一开始结果也是对的:
\>>> add_end()
[‘END’]
但是,再次调用add_end()时,结果就不对了:
\>>> add_end()
[‘END’, ‘END’]
\>>> add_end()
[‘END’, ‘END’, ‘END’]
很多初学者很疑惑,默认参数是[],但是函数似乎每次都“记住了”上次添加了’END’后的list。
原因解释如下:
Python函数在定义的时候,默认参数L的值就被计算出来了,即[],因为默认参数L也是一个变量,它指向对象[],每次调用该函数,如果改变了L的内容,则下次调用时,默认参数的内容就变了,不再是函数定义时的[]了。
所以,定义默认参数要牢记一点:默认参数必须指向不变对象!
要修改上面的例子,我们可以用None这个不变对象来实现:
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
现在,无论调用多少次,都不会有问题:
\>>> add_end()
[‘END’]
\>>> add_end()
[‘END’]
为什么要设计str、None这样的不变对象呢?因为不变对象一旦创建,对象内部的数据就不能修改,这样就减少了由于修改数据导致的错误。此外,由于对象不变,多任务环境下同时读取对象不需要加锁,同时读一点问题都没有。我们在编写程序时,如果可以设计一个不变对象,那就尽量设计成不变对象。
可变参数:
参数个数不确定,可以把a,b,c……作为一个list或tuple传进来,函数定义如下:
def calc(numbers):
for i in numbers:
在调用的时候,需要先组装出一个list或tuple:
\>>> calc([1, 2, 3])
如果利用可变参数,函数的参数改为可变参数:
def calc(*numbers):
for n in numbers:
调用函数的方式可以简化成这样:
\>>> calc(1, 2, 3)
定义可变参数和定义list或tuple参数相比,仅仅在参数前面加了一个*号。在函数内部,参数numbers接收到的是一个tuple,因此,函数代码完全不变。但是,调用该函数时,可以传入任意个参数,包括0个参数:calc()
如果已经有一个list或者tuple,要调用一个可变参数怎么办?可以这样做:
\>>> nums = [1, 2, 3]
\>>> calc(nums[0], nums[1], nums[2])
但是这样太繁琐,可以在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去:
\>>> nums = [1, 2, 3]
\>>> calc(*nums)
关键字参数:
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。
def person(name, age, **kw):
函数person除了必选参数name和age外,还接受关键字参数kw。在调用该函数时,可以只传入必选参数:
\>>> person(‘Michael’, 30)
也可以传入任意个数的关键字参数:
\>>> person(‘Bob’, 35, city=’Beijing’)
关键字参数可以扩展函数的功能。比如,在person函数里,可以保证能接收到name和age这两个参数,但是,如果调用者愿意提供更多的参数,函数也能收到。试想做一个用户注册的功能,除了用户名和年龄是必填项外,其他都是可选项,利用关键字参数来定义这个函数就能满足注册的需求。
也可以先组装出一个dict,然后,把该dict转换为关键字参数传进去:
\>>> kw = {‘city’: ‘Beijing’, ‘job’: ‘Engineer’}
\>>> person(‘Jack’, 24, city=kw[‘city’], job=kw[‘job’]) 或者 person(‘Jack’, 24, **kw)
参数组合:
将上面三种参数组合:def func(a, b, c=0, args,**kw): 解释器自动按照参数位置和参数名把对应的参数传进去所以,对于任意函数,都可以通过类似func(\args, **kw)的形式调用它,无论它的参数是如何定义的。
匿名函数:lambda lambda [arg1 [,arg2, ….argn]] : expression
用lambda关键词能创建小型匿名函数。这种函数得名于省略了用def声明函数的标准步骤。
Lambda函数能接收任何数量的参数但只能返回一个表达式的值,同时只能不能包含命令或多个表达式。
匿名函数不能直接调用print,因为lambda需要一个表达式。lambda函数拥有自己的名字空间,且不能访问自有参数列表之外或全局名字空间里的参数。虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。
模块就是一个Python文件,只有导入import了模块你才能使用模块里的函数。当解释器遇到import语句,如果模块在当前的搜索路径就会被导入。
from modname import funcname1,funcname2….导入某模块中的具体某个函数。
模块搜索路径存存储在system模块的sys.path变量中。变量里包含当前目录,PYTHONPATH(就是Python中lib的路劲)和由安装过程决定的默认目录。一个Python表达式可以访问局部命名空间和全局命名空间里的变量。如果一个局部变量和一个全局变量重名,则局部变量会覆盖全局变量。
命名空间
每个函数都有自己的命名空间。类的方法的作用域规则和通常函数的一样。Python会智能地猜测一个变量是局部的还是全局的,它假设任何在函数内赋值的变量都是局部的。因此,如果要给全局变量在一个函数里赋值,必须使用global语句。
global VarName的表达式会告诉Python, VarName是一个全局变量,这样Python就不会在局部命名空间里寻找这个变量了。
a=0;
def sum():
global a #若将其注释掉将出现错误 UnboundLocalError: local variable 'a' referenced before assignment
a +=1
print a
包
包是一个分层次的目录结构,例如你要在A文件夹下有三个a1.py,a2.py,a3.py。这时可在A下创建init.py文件,然后再里面使用显示的导入语句,
import a1 from a1; import a2 from a2; import a3 from a3; 这样就导入A包的时候这些类就全都是可用的了,import A; A.a1();这就是包的使用方法。
文件I/O
raw_input(提示) 函数从标准输入读取一个行,并返回一个字符串(去掉结尾的换行符)
input(提示) 函数和raw_input(提示) 函数基本可以互换,但是input会假设你的输入是一个有效的Python表达式,并返回运算结果。
open(filename,mode,buffering):打开一个文件
Write()方法可将任何字符串写入一个打开的文件,不在字符串的结尾不添加换行符(‘\n’)。
read()方法从一个打开的文件中读取一个字符串。
Tell()方法告诉你文件内的当前位置;换句话说,下一次的读写会发生在文件开头这么多字节之后:
seek(offset [,from])方法改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。
面向对象
在python中实现数据隐藏很简单,不需要在前面加什么关键字,只要把类变量名或成员函数前面加两个下划线即可实现数据隐藏的功能,这样,对于类的实例来说,其变量名和成员函数是不能使用的,对于其类的继承类来说,也是隐藏的,这样,其继承类可以定义其一模一样的变量名或成员函数名,而不会引起命名冲突。Python不允许实例化的类访问隐藏数据,但你可以使用object._className__attrName访问属性。
参考的都是网上资料