记录python学习过程
#! /usr/bin/python
组织行 ――源文件的头两个字符是#!,后面跟着一个程序.作用是告诉用户的程序在执行的时候使用哪个解释器。
python 区分大小写,确保在每一行的开始字符前没有空格或者制表符
运行程序
1. python test.py 用于运行指定路径的python程序
2. ./test.py 用于在程序的当前目录下
3. test 可以将程序改成任意名字放在环境变量的目录下,也可以通过运行PATH=$PATH:/home/test 将目录/home/test 添加到环境变量中
当需要获取一个函数或者语句的帮助信息时可以使用help,按q退出帮助信息
如:help (str)
help ('print') 获取命令有帮助信息时需要将命令单引号括起来
python 有4种类型的数
整数:1,2
长整数:122222222222222222222222222222222,数值比较大的整数
浮点数:2.11,52.3E-4 E-4表示10的4次方
复数:(-5+4j),(2.3-4.6j)
字符串
单引号:‘this is a desk'
双引号:"this is a desk " 与单引号相同
三引号‘’‘或者“”“:用于表示多行的字符串,在三引号之间可以随意使用单引号及双引号
转义符 \:用于表示特殊字符,如:\ 需要用\\来表示;'what's '需要用‘what\'s';或者使用“what's”
在一个字符串中如果行未有一个单独的\,则表示字符串会在下一行继续,而不是开始新的一行
自然字符串:用于表示不需要使用转义符处理的普通字符串,通过在字符串前加上r或者R来指定。如:r"what is your name \n"
Unicode字符串:书写国际文本的标准方法,在字符串前加上u或者U
字符串是不可变的,按字面级意义连字符串:如:‘what\'s' 'your name'会自动转为"what's your name"
最好用自然字符串处理正则表达式,否则会需要使用很多\。如:‘\\1'写成r'\1'
标识符
是用来标识某种东西的名字,规则如下:
第一个字符必须是英文字母(大小写)或者一个下划线(_)
后面部分可以由字母(大小写)、下划线(_)、或数字(0-9)组成
大小写敏感
有效的标识名:i,_my_name,name_34
无效的标识名:2,5name,my-name
变量可以处理不同的类型的值,基本的类型是数和字符串。
运算符
+、-、*、<、>、<=、>=、==、!=、not、and、or 、/、//(取整)、**(幂3**3即:3*3*3)、%(取余)、《(左移)、》(右移
,即将一个数的比特向左或者向右移一定的数目,因为每个数在内存中都表示为比特或二进制数字即0和1。如2<<2 得到8,--2按比特表示为10,左移2位后为1000,为二进制数8)、&(与)、|(或)、^(异或)、~(按位翻转)
控制流语句
if语句
if……:
elif……:
else:
注意if语句在结尾处包含一个冒号――它告诉Python下面跟着一个语句块,elif和else从句都必须在逻辑行结尾处有一个冒号,下面跟着一个>相应的语句块,也可以在一个if块中使用另外一个if语句,等等――这被称为嵌套的if语句,elif和else部分是可选的
在Python执行完一个完整的if语句以及与它相关联的elif和else从句之后,它移向if语句块的下一个语句。
while语句
while……:
else:
当while循环条件变为False的时候,else块才被执行――这甚至也可能是在条件第一次被检验的时候。如果while循环有一个else从句,它将始
终被执行,除非你的while循环将永远循环下去不会结束
for循环
for……:
else:
我们所做的只是提供两个数,range返回一个序列的数。这个序列从第一个数开始到第二个数为止。例如,range(1,5)给出序列[1, 2, 3, 4]。默认地,range的步长为1。如果我们为range提供第三个数,那么它将成为步长。例如,range(1,5,2)给出[1,3]。记住,range 向上 延伸
到第二个数,即它不包含第二个数。
如:c表达式:for (int 1=0;i<5;i++)换成python会是这样for i in range(0,5)
记住,else部分是可选的。如果包含else,它总是在for循环结束后执行一次,除非遇到break语句
break语句
用来终止循环语句的,即哪怕循环条件没有称为False或序列还没有被完全递归,也停止执行循环语句。
如果你从for或while循环中 终止 ,任何对应的循环else块将不执行.
continue语句
continue
仅当条件满足时才会忽略continue之后的语句,当条件不满足时后面的语句才会被执行.该语句同样对for循环有效
函数
自定义函数
def test():
调用函数
test()
函数形参
函数取得的参数是你提供给函数的值,这样函数就可以利用这些值做一些事情。这些参数就像变量一样,只不过>它们的值是在我们调用函数的时候定义的,而非在函数本身内赋值。
参数在函数定义的圆括号对内指定,用逗号分割。当我们调用函数的时候,我们以同样的方式提供值。注意――函>数中的参数名称为:形参, 而你提供给函数调用的值称为:实参 。
例子:
#! /usr/bin/python
def printMax(a, b): #本例中,a,b为形参
if a > b:
print a, 'is maximum'
else:
print b, 'is maximum'
printMax(3, 4) # directly give literal values
x = 5
y = 7
printMax(x, y) #调用函数时传递的值则为实参
局部变量
局部变量在声明时与函数外具有相同名称的其他变量没有任何关系,对于函数来说是局部的。所有变量的作用域>是它们被定义的块,即从它们的名称被定义的那点开始。
全局变量
要使用一个定义在函数外的变量赋值,那么你就得告诉Python这个变量名不是局部的,而是 全局 的。我们使用global语句完成这一功能。没有global语句,是不可能为定义在函数外的变量赋值的。
默认参数值
对于一些函数,如果希望它的一些参数是 可选 的,如果用户不想要为这些参数提供值的话,这些参数就使用默>认值。这个功能借助于默认参数值完成。你可以在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。只有在形参表末尾的那些参数可以有默认参数值,即你不能在声明函数形参的时候,先声明>有默认值的形参而后声明没有默认值的形参。
关键参数
如果某个函数有许多参数,而你只想指定其中的一部分,那么你可以通过命名来为这些参数赋值――这被称作 关键参数 ――我们使用名字(关键字)而不是位置来给函数指定实参。这样做有两个 优势 ――一,由于我们不必担心参数的顺序,使用函数变得更加简单了。二、假设其他参数都有默认值,我们可以只给我们想要的那些参数赋值。
例:
#!/usr/bin/python
def
func
(a, b=
5
, c=
10
):
print
'a is'
, a,
'and b is'
, b,
'and c is'
, c
func(
3
,
7
)
func(
25
, c=
24
)
func(c=
50
, a=
100
)
解析:
第一个函数func(3,7),默认参数b=5,c=10,调用函数时会将3,7依次传递给a,b,c因为只有两个,故:a=3,b=7,c=10
第二个函数func(25,c=24),因为a没有值,首先将25赋值给a,指定必定c的值,故:a=25,b=5,c24
第三个函数func(c=50,a=100),类推:a=100,b=5,c=50
return语句
用于返回函数,即跳出函数,也可用于返回函数中的一个值
例:
#!/usr/bin/python
def max(x,y):
if x>y:
return x
else:
return y
print max(4,5)
注意,没有返回值的return
语句等价于return None
。None
是Python中表示没有任何东西的特殊类型。例如,如果一个变量的值为None
,可以表示它没有值。
DocStrings
文档字符串,文档字符串的惯例是一个多行字符串,它的首行以大写字母开始,句号结尾。第二行是空行,从第>三行开始是详细的描述。使用__doc__(注意双下划线)调用printMax函数的文档字符串属性(属于函数的名称)
例:
#!/usr/bin/python
def aa(message,a1=1):
'''This is test.
are you ok?
now put up your hand.'''
print message * a1
aa('how')
aa('are you',5)
def max(x,y):
if x>y:
return x
else:
return y
print aa(4,5)
print aa.__doc__ #打印文档字符串,注意格式:函数名.__doc__ (双下划线_doc_双下划线)
模块
模块就是一个包含了所有你定义的函数和变量的文件。为了在其他程序中重用模块,模块的
文件名必须以.py为扩展名。模块可以从其他程序 输入 以便利用它的功能。这也是我们使>用Python标准库的方法。
利用import语句 输入 模块。基本上,这句语句告诉Python,我们想要使用这个模块。
字节编译的.pyc文件
输入一个模块相对来说是一个比较费时的事情,所以Python做了一些技巧,以便使输入模块
更加快一些。一种方法是创建 字节编译的文件 ,这些文件以.pyc作为扩展名。字节编译的
文件与Python变换程序的中间状态有关。当你在下次从别的程序输入这个模块的时候,.pyc文件是十分有用的――它会快得多,因为一部分输入模块所需的处理已经完成了。另外,这些
字节编译的文件也是与平台无关的。
模块的__name__
每个模块都有一个名称,在模块中可以通过语句来找出模块的名称。这在一个场合特别有用
――就如前面所提到的,当一个模块被第一次输入的时候,这个模块的主块将被运行。假如我
们只想在程序本身被使用的时候运行主块,而在它被别的模块输入的时候不运行主块,我们
该怎么做呢?这可以通过模块的__name__属性完成。
创建你自己的模块
它与我们普通的Python程序相比并没有什么特别之处。如何在别的Python程序中使用这个模块?
记住这个模块应该被放置在我们输入它的程序的同一个目录中,或者在sys.path
所列目录之一。注意使用了点号来引用模块的成员
例:
test1.py #打印字符串的函数
#!/usr/bin/python
def aa(message,a1=1):
'''This is test.
are you ok?
now put up your hand.'''
print message * a1
test2.py
#!/usr/bin/python
import test1
test1.aa("are",10)
from test1 import aa
aa("test",5)
调用模块有两种方法:import 和 from……import
dir()函数
内建的dir
函数用来列出模块定义的标识符。标识符有函数、类和变量。
例:
#!/usr/bin/python
import test2
print dir(test2)
dir()列出标识符如下:
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'aa', 'test1']
数据结构
列表
list
是处理一组有序项目的数据结构,即你可以在一个列表中存储一个 序列 的项目。在每个项目之间用逗号分割,Python列表从0开始计数
列表中的项目应该包括在方括号中,这样Python就知道你是在指明一个列表。一旦你创建了一个列表,你可以添加、删除或是搜索列表中的项目。由于你可以增加或删除项目,我们说列表是 可变的 数据类型,即这种类型是可以被改变的。
如:test['apple','rice']
元组
元组和列表十分类似,只不过元组和字符串一样是 不可变的 即你不能修改元组。元组通过圆括号中用逗号分割的项目定义。元组通常用在使语句或用户定义的函数能够安全地采用一组值的时候,即被使用的元组的值不会改变。
如:test('this','that')
例:
#!/usr/bin/python
testlist=['this','is','a','desk'] #列表用中括号表示
print testlist[0],testlist[1],testlist[2],testlist[3]
testlist.append('?')
print testlist
testyz=('one','two','three') #元组用括号表示
print 'this len is:',len(testyz)
print testyz
print testyz[1][1]
#读取元组testyz中的第2个项目中的第2个值,即:w,注意表示方法,元组名[][],元组值从0开始。
字典
字典类似于你通过联系人名字查找地址和联系人详细情况的地址簿,即,我们把键(名字)和值(详细情况)联系在一起。注意,键必须是唯一的,就像如果有两个人恰巧同名的话,你无法找到正确的信息。
注意,你只能使用不可变的对象(比如字符串)来作为字典的键,但是你可以使用不可变或可变的对象作为字典的值。基本说来就是,你应该只使用简单的对象作为键。
键值对在字典中以这样的方式标记:d = {key1 : value1, key2 : value2 }
。注意它们的键/值对用冒号分割,而各个对用逗号分割,所有这些都包括在花括号中。
记住字典中的键/值对是没有顺序的。如果你想要一个特定的顺序,那么你应该在使用前自己对它们排序。
例:
#!/usr/bin/python
cd={'one' : 'is a number 1',
'two' : 'is a number 2',
'four' : 'is a number 4'
}
print 'one %s' % cd['one']
字符串的操作
在程序中使用的字符串都是str
类的对象,要了解这些方法的完整列表,请参见help(str)
startwith
方法是用来测试字符串是否以给定字符串开始。in
操作符用来检验一个给定字符串是否为另一个字符串的一部分。
find
方法用来找出给定字符串在另一个字符串中的位置,或者返回-1以表示找不到子字符串。str
类也有以一个作为分隔符的字符串join
序列的项目的整洁的方法,它返回一个生成的大字符串。
面向对象的编程
在我们的程序中,我们都是根据操作数据的函数或语句块来设计程序的。这被称为面向过程的编程。还有一种把数据和功能结合起来,用称为对象的东西包裹起来组织程序的方法。这种方法称为面向对象的编程理念。在大多数时候你可以使用过程性编程,但是有些时候当你想要编写大型程序或是寻求一个更加合适的解决方案的时候,你就得使用面向对象的编程技术。
类和对象是面向对象编程的两个主要方面。类创建一个新类型,而对象这个类的实例 。这类似于你有一个int
类型的变量,这存储整数的变量是int
类的实例(对象)。注意,即便是整数也被作为对象(属于int
类
对象可以使用普通的属于对象的变量存储数据。属于一个对象或类的变量被称为域。对象也可以使用 属于 类的函数来具有功能。这样的函数被称为类的方法。这些术语帮助我们把它们与孤立的函数和变量区分开来。域和方法可以合称为类的属性。
域有两种类型――属于每个实例/类的对象或属于类本身。它们分别被称为实例变量和类变量。
类使用class
关键字创建。类的域和方法被列在一个缩进块中。
self
类的方法与普通的函数只有一个特别的区别――它们必须有一个额外的第一个参数名称,但是在调用这个方法的时候你不为这个参数赋值,Python会提供这个值。这个特别的变量指对象本身,你可以给这个参数任何名称,按照惯例它的名称是self。
假如你有一个类称为MyClass和这个类的一个实例MyObject。当你调用这个对象的方法MyObject.method(arg1, arg2)的时候,这会由Python自动转为MyClass.method(MyObject, arg1, arg2)――这就是self的原理了。
这也意味着如果你有一个不需要参数的方法,你还是得给这个方法定义一个self参数。
例:
#!/usr/bin/python
# Filename: simplestclass.py
class Person:
def sayHi(self):
print 'Hello, how are you?'
p = Person()
p.sayHi()
print p
我们使用class语句后跟类名,创建了一个新的类。这后面跟着一个缩进的语句块形成类体。在这个例子中,我们创建了一个函数sayHi,接下来,我们使用类名后跟一对圆括号来创建一个对象/实例。注意sayHi方法没有任何参数,但仍然在函数定义时有self。
__init__方法
__init__方法在类的一个对象被建立时,马上运行。
这个方法可以用来对你的对象做一些你希望的 初始化 。注意,这个名称的开始和结尾都是双下划线。
Python中所有的类成员(包括数据成员)都是 公共的 ,所有的方法都是 有效的 。
只有一个例外:如果你使用的数据成员名称以 双下划线前缀 比如__privatevar,Python的名称管理体系会有效地把它作为私有变量。
这样就有一个惯例,如果某个变量只想在类或对象中使用,就应该以单下划线前缀。而其他的名称都将作为公共的,可以被其他类/对象使用。记住这只是一个惯例,并不是Python所要求的(与双下划线前缀不同)。
同样,注意__del__方法与 destructor 的概念类似。
输入/输出
在很多时候,你会想要让你的程序与用户(可能是你自己)交互。你会从用户那里得到输入,然后打印一些结果。我们可以分别使用raw_input和print语句来完成这些功能。对于输出,你也可以使用多种多样的str(字符串)类。例如,你能够使用rjust方法来得到一个按一定宽度右对齐的字符串。利用help(str)获得更多详情。
另一个常用的输入/输出类型是处理文件。创建、读和写文件的能力是许多程序所必需的
文件
你可以通过创建一个file类的对象来打开一个文件,分别使用file类的read、readline或write方法来恰当地读写文件。对文件的读写能力依赖于你在打开文件时指定的模式。最后,当你完成对文件的操作的时候,你调用close方法来告诉Python我们完成了对文件的使用。
#!/usr/bin/python
# Filename: using_file.py
poem = '''\
Programming is fun
When the work is done
if you wanna make your work also fun:
use Python!
'''
f = file('poem.txt', 'w') # open for 'w'riting
f.write(poem) # write text to file
f.close() # close the file
f = file('poem.txt')
# if no mode is specified, 'r'ead mode is assumed by default
while True:
line = f.readline()
if len(line) == 0: # Zero length indicates EOF
break
print line,
# Notice comma to avoid automatic newline added by Python
f.close() # close the file
首先,我们通过指明我们希望打开的文件和模式来创建一个file类的实例。模式可以为读模式('r')、写模式('w')或追加模式('a')。事实上还有多得多的模式可以使用,你可以使用help(file)来了解它们的详情。
我们首先用写模式打开文件,然后使用file类的write方法来写文件,最后我们用close关闭这个文件。
接下来,我们再一次打开同一个文件来读文件。如果我们没有指定模式,读模式会作为默认的模式。在一个循环中,我们使用readline方法读文件的每一行。这个方法返回包括行末换行符的一个完整行。所以,当一个 空的 字符串被返回的时候,即表示文件末已经到达了,于是我们停止循环。
注意,因为从文件读到的内容已经以换行符结尾,所以我们在print语句上使用逗号来消除自动换行。最后,我们用close关闭这个文件。
储存器
Python提供一个标准的模块,称为pickle
。使用它你可以在一个文件中储存任何Python对象,之后你又可以把它完整无缺地取出来。这被称为 持久的 储存对象。
还有另一个模块称为cPickle
,它的功能和pickle
模块完全相同,只不过它是用C语言编写的,因此要快得多(比pickle
快1000倍)。你可以使用它们中的任一个,而我们在这里将使用cPickle
模块。记住,我们把这两个模块都简称为pickle
模块。
例:存储与取存储
import
cPickle
as p
#import pickle as p
shoplistfile =
'shoplist.data'
# the name of the file where we will store the object
shoplist = [
'apple'
,
'mango'
,
'carrot'
]
# Write to the file
f =
file
(shoplistfile,
'w'
)
p.dump(shoplist, f) # 将shoplist的内容存储到文件 f 中
f.close()
del
shoplist
# remove the shoplist
# Read back from the storagef =
file
(shoplistfile)
storedlist = p.load(f) #重新加载print
storedlist
为了在文件里储存一个对象,首先以写模式打开一个file
对象,然后调用储存器模块的dump
函数,把对象储存到打开的文件中。这个过程称为 储存 。
接下来,我们使用pickle
模块的load
函数的返回来取回对象。这个过程称为 取储存
异常处理
我们可以使用try..except
语句来处理异常。我们把通常的语句放在try-块中,而把我们的错误处理语句放在except-块中。
#!/usr/bin/python
# Filename: try_except.pyimport
sys
try
:
s =
raw_input
(
'Enter something --> '
)
except
EOFError:
print
'\nWhy did you do an EOF on me?'
sys
.exit()
# exit the program
except
:
print
'\nSome error/exception occurred.'
# here, we are not exiting the program
print
'Done'
我们把所有可能引发错误的语句放在try
块中,然后在except
从句/块中处理所有的错误和异常。except
从句可以专门处理单一的错误或异常,或者一组包括在圆括号内的错误/异常。如果没有给出错误或异常的名称,它会处理所有的错误和异常。对于每个try
从句,至少都有一个相关联的except
从句。
如果某个错误或异常没有被处理,默认的Python处理器就会被调用。它会终止程序的运行,并且打印一个消息,我们已经看到了这样的处理。
Python标准库
os模块
sys模块
特殊的方法
一般说来,特殊的方法都被用来模仿某个行为。一些特殊的方法:
__init__(self,...) 这个方法在新建对象恰好要被返回使用之前被调用
__del__(self) 恰好在对象要被删除之前调用。
__str__(self) 在我们对对象使用print
语句或是使用str()
的时候调用。
__lt__(self,other) 当使用 小于 运算符(<)的时候调用。类似地,对于所有的运算符(+,>等等)都有特殊的方法。
__getitem__(self,key) 使用x[key]
索引操作符的时候调用。
__len__(self) 对序列对象使用内建的len()
函数的时候调用。
列表综合
通过列表综合,可以从一个已有的列表导出一个新的列表。例如,你有一个数的列表,而你想要得到一个对应的列表,使其中所有大于2的数都是原来的2倍。对于这种应用,列表综合是最理想的方法。
例:
#!/usr/bin/python
# Filename: list_comprehension.pylistone = [
2
,
3
,
4
]
listtwo = [
2
*i
for
i
in
listone
if
i >
2
]
print
listtwo
为满足条件(
if i > 2
)的数指定了一个操作(2*i
),从而导出一个新的列表。注意原来的列表并没有发生变化。在很多时候,我们都是使用循环来处理列表中的每一个元素,而使用列表综合可以用一种更加精确、简洁、清楚的方法完成相同的工作。
在函数中接收元组和列表
当要使函数接收元组或字典形式的参数的时候,有一种特殊的方法,它分别使用*
和**
前缀。这种方法在函数需要获取可变数量的参数的时候特别有用。
>>> def powersum(power, *args):
... '''Return the sum of each argument raised to specified power.'''
... total = 0
... for i in args:
... total += pow(i, power) ;pow(a,b)函数,用于求a的b次方
... return total
...
>>> powersum(2, 3, 4)
25
>>> powersum(2, 10)
100
由于在args
变量前有*
前缀,所有多余的函数参数都会作为一个元组存储在args
中。如果使用的是**
前缀,多余的参数则会被认为是一个字典的键/值对
lambda形式
lambda
语句被用来创建新的函数对象,并且在运行时返回它们。
#!/usr/bin/python
# Filename: lambda.py
def make_repeater(n):
return lambda s: s*n
twice = make_repeater(2)
print twice('word')
print twice(5)
使用了make_repeater
函数在运行时创建新的函数对象,并且返回它。lambda
语句用来创建函数对象。本质上,lambda
需要一个参数,后面仅跟单个表达式作为函数体,而表达式的值被这个新建的函数返回。注意,即便是print
语句也不能用在lambda形式中,只能使用表达式。
exec和eval语句
exec
语句用来执行储存在字符串或文件中的Python语句。例如,我们可以在运行时生成一个包含Python代码的字符串,然后使用exec
语句执行这些语句。
exec 'print "Hello World"'
eval
语句用来计算存储在字符串中的有效Python表达式
eval('2*3')