小朋友学Python(3)
运算符
一、基本运算符
Python运算符多数与C/C++/Java类似,但有少数不一样。
“/”表示求商,“//”求商的整数部分。11 / 2 = 5.500000, 11 // 2 = 5
“**”表示求幂。2 ** 5 = 32
例1
a = 10
b = 3
x = a / b
y = a // b
z = a**b
print x,y,z
c = float(b)
m = a / c
n = a // c
print m,n
运行结果:
3 3 1000
3.33333333333 3.0
二、成员运算符in和not in
in : 如果在指定的序列中找到值返回 True,否则返回 False
not in : 如果在指定的序列中没有找到值返回 True,否则返回 False
例2
a = 1
b = 20
list = [1, 2, 3, 4, 5 ];
if ( a in list ):
print "a is in the list"
else:
print "a is not in the list"
if ( b not in list ):
print "b is not in the list"
else:
print "b is in the list"
运行结果:
a is in the list
b is not in the list
三、身份运算符is和is not
is : 判断两个标识符是不是引用自一个对象
is not : 判断两个标识符是不是引用自不同的对象
例3
a = 20
b = 20
if ( a is b ):
print "a and b is the same object"
else:
print "a and b is not the same object"
if ( a is not b ):
print "a and b is not the same object"
else:
print "a and b is the same object"
b = 30
if ( a is b ):
print "a and b is the same object"
else:
print "a and b is not the same object"
运行结果:
a and b is the same object
a and b is the same object
a and b is not the same object
is与==的区别
is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等
例4 (以下代码位于Python交互式环境)
>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
>>> b = a[:]
>>> b is a
False
>>> b == a
True
说明,b =a[:],这里冒号前面和后面都没有数字,表示取a的第一个元素到最后一个元素,放到另一个对象b里。所以b与a里的数据相同,但不是同一个对象。
四、运算符优先级
运算符 | 描述 |
---|---|
() | 括号(最高优先级) |
** | 指数 |
~ + - | 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) |
* / % // | 乘,除,取模和取整除 |
+ - | 加法减法 |
>> << | 右移,左移运算符 |
& | 位 'AND' |
^ | 位运算符 |
<= < > >= | 比较运算符 |
<> == != | 等于运算符 |
= %= /= //= -= += *= **= | 赋值运算符 |
is, is not | 身份运算符 |
in, not in | 成员运算符 |
not, or, and | 逻辑运算符 |
循环
一、while循环
例1
count = 0
while (count < 9):
print 'The count is:', count
count = count + 1
print "Good bye!"
运行结果:
The count is: 0
The count is: 1
The count is: 2
The count is: 3
The count is: 4
The count is: 5
The count is: 6
The count is: 7
The count is: 8
Good bye!
例2 (while…else句式)
count = 0
while count < 5:
print count, " is less than 5"
count = count + 1
else:
print count, " is not less than 5"
运行结果:
0 is less than 5
1 is less than 5
2 is less than 5
3 is less than 5
4 is less than 5
5 is not less than 5
二、for循环
例3
# -*- coding: UTF-8 -*-
for letter in 'Python': # 第一个实例
print '当前字母 :', letter
fruits = ['banana', 'apple', 'mango']
for fruit in fruits: # 第二个实例
print '当前水果 :', fruit
print "Good bye!"
运行结果:
当前字母 : P
当前字母 : y
当前字母 : t
当前字母 : h
当前字母 : o
当前字母 : n
当前水果 : banana
当前水果 : apple
当前水果 : mango
Good bye!
三、Pass语句
例4
# -*- coding: UTF-8 -*-
# 输出 Python 的每个字母
for letter in 'Python':
if letter == 'h':
pass
print '这是 pass 块'
print '当前字母 :', letter
print "Good bye!"
运行结果:
当前字母 : P
当前字母 : y
当前字母 : t
这是 pass 块
当前字母 : h
当前字母 : o
当前字母 : n
Good bye!
日期和时间
一、获取当前时间戳
例1
import time
now = time.time()
print now
运行结果:
1512884891.53
说明:
这里得到的时间是时间戳(timestamp),是从1970年1月1日0时0分开始计算的,单位是秒。
时间戳单位最适于做日期运算。但是1970年之前的日期就无法以此表示了。太遥远的日期也不行,UNIX和Windows只支持到2038年。
二、获取当前时间
例2
import time
localtime = time.localtime(time.time())
print localtime
运行结果:
time.struct_time(tm_year=2018, tm_mon=1, tm_mday=2, tm_hour=17, tm_min=27, tm_sec=59, tm_wday=1, tm_yday=2, tm_isdst=0)
说明:
struct_time叫做时间元组,其数据结构为
属性 | 意义 | 值 |
---|---|---|
tm_year | 四位数的年 | 2018 |
tm_mon | 月 | 1到12 |
tm_mday | 日 | 1到31 |
tm_hour | 小时 | 0到23 |
tm_min | 分钟 | 0到59 |
tm_sec | 秒 | 0到60(60是闰秒) |
tm_wday | 星期几 | 0到6(0是星期一) |
tm_yday | 一年的第几日 | 1到366 |
tm_isdst | 夏令时 | 1:夏令时; 0:非夏令时 |
三、获取格式化的时间
你可以根据需求选取各种格式,但是最简单的获取可读的时间模式的函数是asctime()
例3
import time
localtime = time.localtime(time.time())
formatTime = time.asctime(localtime)
print formatTime
运行结果:
Tue Jan 02 17:51:42 2018
四、格式化日期
例4
import time
print time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print time.strftime("%a %b %d %H:%M:%S %Y", time.localtime())
# convert time to timestamp
a = "Sat Mar 28 22:24:24 2016"
print time.mktime(time.strptime(a,"%a %b %d %H:%M:%S %Y"))
运行结果:
2018-01-02 17:57:19
Tue Jan 02 17:57:19 2018
1459175064.0
python中时间日期格式化符号:
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
%I 12小时制小时数(01-12)
%M 分钟数(00=59)
%S 秒(00-59)
%a 本地简化星期名称
%A 本地完整星期名称
%b 本地简化的月份名称
%B 本地完整的月份名称
%c 本地相应的日期表示和时间表示
%j 年内的一天(001-366)
%p 本地A.M.或P.M.的等价符
%U 一年中的星期数(00-53)星期天为星期的开始
%w 星期(0-6),星期天为星期的开始
%W 一年中的星期数(00-53)星期一为星期的开始
%x 本地相应的日期表示
%X 本地相应的时间表示
%Z 当前时区的名称
%% %号本身
五、获取某月日历
例5
import calendar
cal = calendar.month(2016, 1)
print cal
运行结果:
January 2016
Mo Tu We Th Fr Sa Su
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
函数
函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码段。
函数能提高应用的模块性,和代码的重复利用率。
Python提供了许多内建函数,比如print()。但编程人员也可以自己创建函数,这叫做用户自定义函数。
一、定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()。
任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。
函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
函数内容以冒号起始,并且缩进。
return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
例1
def printme( str ):
" Print input string "
print str
return
二、函数调用
定义一个函数只是给了函数一个名称,指定了函数里包含的参数,和代码块结构。
这个函数的基本结构完成以后,可以通过另一个函数调用执行,也可以直接从Python提示符执行。
例2
# define function
def printme( str ):
"Print input string"
print str;
return;
# invoke function
printme("invoke self defined function!");
printme("invoke the same function again");
运行结果:
invoke self defined function!
invoke the same function again!
三、参数传递
在 python 中,类型属于对象,变量是没有类型的:
a = [1,2,3]
a = "Newbie"
以上代码中,[1,2,3] 是 List 类型,"Newbie" 是 String 类型,而变量 a 是没有类型,它仅仅是一个对象的引用(一个指针),可以是 List 类型对象,也可以指向 String 类型对象。
(一)可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
不可变类型:变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变a的值,相当于新生成了a。
可变类型:变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
(二)python 函数的参数传递
不可变类型:类似 c++ 的值传递,如 整数、字符串、元组。如fun(a),传递的只是a的值,没有影响a对象本身。比如在 fun(a)内部修改 a 的值,只是修改另一个复制的对象,不会影响 a 本身。
可变类型:类似 c++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后fun外部的la也会受影响
(三)python 传不可变对象的例子
例3
def ChangeInt( a ):
a = 10
b = 2
ChangeInt(b)
print b
运行结果:
2
(四)传可变对象例子
例4
def changeme( mylist ):
"modify input list"
mylist.append([1,2,3]);
print mylist
return
mylist = [10,20,30];
changeme( mylist );
print mylist
因为list是可变对象,所以函数内外的mylist指向了同一个对象,值自然也就相同。故运行结果如下:
[10, 20, 30, [1, 2, 3]]
[10, 20, 30, [1, 2, 3]]
四、参数类型
以下是调用函数时可使用的正式参数类型:
必备参数
关键字参数
默认参数
不定长参数
(一)必备参数
必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。
调用printme()函数,你必须传入一个参数,不然会出现语法错误:
例5
def printme( str ):
print str;
return;
printme();
运行结果:
Traceback (most recent call last):
File "test.py", line 5 in <module>
printme();
TypeError: printme() takes exactly 1 argument (0 given)
(二)关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。
以下实例在函数 printme() 调用时使用参数名做为关键字:
例6
def printme( str ):
print str;
return;
printme( str = "Hello World!");
运行结果:
Hello World!
注意,这里str是关键字,所以不能改为别的名称。以下都是错的:
s = “Hello World!”
abc = “Hello World!”
下例能将关键字参数顺序不重要展示得更清楚:
例7
def printinfo( name, age ):
print "Name: ", name;
print "Age: ", age;
return;
printinfo( age=9, name="Theodore" );
运行结果:
Name: Theodore
Age: 9
(三)缺省参数
调用函数时,缺省参数的值如果没有传入,则被认为是取默认值。
例8
def printinfo( name, age = 18 ):
print "Name: ", name
print "Age ", age;
return;
printinfo( age=9, name="Theodore" )
printinfo( name="Li Lei" )
运行结果:
Name: Theodore
Age: 9
Name: Li Lei
Age: 18
(四)不定长参数
你在定义函数时可能事先不知道函数被调用时会传入多少个参数,这时你可以声明不定长参数。
不定长参数声明时不会命名,基本语法如下:
def functionname([formal_args,] *var_args_tuple ):
"函数说明"
function_suite
return [expression]
加了星号的变量名会存放所有未命名的变量参数。
例9
def printinfo( arg1, *vartuple ):
print arg1
for var in vartuple:
print var
return
printinfo( 10 )
printinfo( 70, 60, 50 )
运行结果:
10
70
60
50
五、匿名函数
python 使用 lambda 来创建匿名函数。
lambda只是一个表达式,函数体比def简单很多。
lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
语法
lambda函数的语法只包含一个语句,如下:
lambda [arg1 [,arg2,.....argn]]:expression
例10
sum = lambda arg1, arg2: arg1 + arg2;
print sum( 10, 20 )
print sum( 20, 20 )
运行结果:
30
40
模块
一、模块的定义
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句。
模块让你能够有逻辑地组织你的 Python 代码段。
把相关的代码分配到一个模块里能让你的代码更好用,更易懂。
模块能定义函数,类和变量,模块里也能包含可执行的代码。
例1: printinfo.py
def print_info(info):
print "Hello:", info
return
二、模块的引入
模块定义好后,我们可以使用 import 语句来引入模块,语法如下:
import module1[, module2[,... moduleN]]
例2:test.py
import printinfo
printinfo.print_info("Python")
运行结果:
Hello: Python
注意,这里printinfo.py和test.py要放在同一个目录下。
三、from … import
Python 的 from 语句让你从模块中导入一个指定的部分到当前命名空间中。语法如下:
from modname import name1[, name2[, ... nameN]]
例如,要导入模块 a的 b 函数,使用如下语句:
from a import b
这个声明不会把整个 a 模块导入到当前的命名空间中,它只会将 a 里的 b 函数引入到执行这个声明的模块的全局符号表。
四、包
包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。
简单来说,包就是文件夹,但该文件夹下必须存在 __init__
.py 文件, 该文件的内容可以为空。__init__
.py用于标识当前文件夹是一个包。
例3
考虑一个在 package_demo目录下的 module1.py、module2.py、__init__
.py 文件,test.py 为测试调用包的代码,目录结构如下:
test.py
package_demo
|-- __init__.py
|-- module1.py
|-- module2.py
__init__.py
中的代码
print 'package_demo initialize'
module1.py的代码
def func1():
print "I am in function 1"
module2.py的代码
def func2():
print "I am in function 2"
test.py的代码
from package_demo import module1
from package_demo import module2
module1.func1()
module2.func2()
运行结果:
文件
Python 提供了必要的函数和方法进行默认情况下的文件基本操作。你可以用 file 对象做大部分的文件操作。
一、打开和关闭文件
例1
(1)创建名为test1.txt的文件,内容为
This is a test file.
(2)在同一目录下新建file1.py文件,内容如下
file = open("test1.txt", "wb")
print "File name: ", file.name
print "Access mode: ", file.mode
print "Closed or not? ", file.closed
file.close()
print "Closed or not? ", file.closed
运行结果:
File name: test1.txt
Access mode: wb
Closed or not? False
Closed or not? True
说明:
(一)open 函数
你必须先用Python内置的open()函数打开一个文件,创建一个file对象,相关的方法才可以调用它进行读写。
语法:
file object = open(file_name [, access_mode][, buffering])
各个参数的细节如下:
(1)file_name:file_name变量是一个包含了你要访问的文件名称的字符串值。
(2)access_mode:access_mode决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,默认文件访问模式为只读(r)。下表是这些模式的总结。
模式 | 描述 |
---|---|
r | 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 |
rb | 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。 |
r+ | 打开一个文件用于读写。文件指针将会放在文件的开头。 |
rb+ | 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。 |
w | 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb | 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
w+ | 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
wb+ | 以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。 |
a | 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
ab | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。 |
a+ | 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。 |
ab+ | 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。 |
(3)buffering: 是一个可选的参数,用来表示缓冲区的策略选择。设置为0时,表示不使用缓冲区,直接读写,仅在二进制模式下有效。设置为1时,表示在文本模式下使用行缓冲区方式。设置为大于1时,表示缓冲区的设置大小。如果参数buffering没有给出,使用默认时,会采用下面策略来选择:
① 对于二进制文件模式时,采用固定块内存缓冲区方式,内存块的大小根据系统设备的分配的磁盘块来决定,如果获取系统磁盘块的大小失败,就使用内部常量io.DEFAULT_BUFFER_SIZE定义的大小。一般的操作系统上,块的大小是4096或者8192字节大小。
② 对于交互的文本文件(采用isatty()判断为True)时,采用一行缓冲区的方式。其它文本文件使用跟二进制一样的方式。
(二)File对象的属性
一个文件被打开后,你有一个file对象,你可以得到有关该文件的各种信息。
以下是和file对象相关的所有属性的列表:
属性 | 描述 |
---|---|
file.closed | 返回true如果文件已被关闭,否则返回false。 |
file.mode | 返回被打开文件的访问模式。 |
file.name | 返回文件的名称。 |
(三)close()方法
close()方法方法关闭打开的文件。关闭的文件无法读取或写入更多东西。文件已被关闭之后任何操作都会引发ValueError。但是调用close()多次是可以的。
当一个文件对象的引用被重新指定给另一个文件时,Python 会关闭之前的文件。
用 close()方法关闭文件是一个很好的习惯。
二、读取文件内容
例2
file = open("test1.txt", "r+")
content = file.read(10)
print content
file.close()
运行结果:
This is a
read()方法
read()方法从一个打开的文件中读取一个字符串。需要重点注意的是,Python字符串可以是二进制数据,而不仅仅是文字。
语法:
fileObject.read([count]);
在这里,被传递的参数是要从已打开文件中读取的字节计数。该方法从文件的开头开始读入,如果没有传入count,它会尝试尽可能多地读取更多的内容,很可能是直到文件的末尾。
三、写入文件
例3
file = open("test2.txt", "wb")
file.write( "I like study Python.");
file.close()
运行结果:
生成test2.txt,并向其写入
I like study Python.
说明:
write()方法
write()方法可将任何字符串写入一个打开的文件。需要重点注意的是,Python字符串可以是二进制数据,而不仅仅是文字。
write()方法不会在字符串的结尾添加换行符('\n'):
语法:
fileObject.write(string);
在这里,被传递的参数是要写入到已打开文件的内容。
四、文件定位
例4
file = open("test1.txt", "r+")
content = file.read(10);
print content
position = file.tell();
print "Current positon: ", position
position = file.seek(0, 0);
content = file.read(5);
print content
position = file.tell();
print "Current positon: ", position
file.close()
运行结果:
This is a
Current position: 10
This
Current position: 5
说明:
(一)tell()方法
告诉你文件内的当前位置;换句话说,下一次的读写会发生在文件开头这么多字节之后。
(二)seek(offset [,from])方法
改变当前文件的位置。Offset变量表示要移动的字节数。From变量指定开始移动字节的参考位置。
如果from被设为0,这意味着将文件的开头作为移动字节的参考位置。如果设为1,则使用当前的位置作为参考位置。如果它被设为2,那么该文件的末尾将作为参考位置。
五、重命名和删除文件
Python的os模块提供了帮你执行文件处理操作的方法,比如重命名和删除文件。
要使用这个模块,你必须先导入它,然后才可以调用相关的各种功能。
rename()方法
rename()方法需要两个参数,当前的文件名和新文件名。
语法:
os.rename(current_file_name, new_file_name)
例5
import os
os.rename( "test1.txt", "test5.txt" )
remove()方法
你可以用remove()方法删除文件,需要提供要删除的文件名作为参数。
语法:
os.remove(file_name)
例6
import os
os.remove("test5.txt")
目录
Python的os模块有许多方法能帮你创建,删除和更改目录。
一、创建目录
mkdir()方法
可以使用os模块的mkdir()方法在当前目录下创建新的目录们。你需要提供一个包含了要创建的目录名称的参数。
语法:
os.mkdir("dirname")
例1:在当前目录下创建一个新目录testdir
import os
os.mkdir("testdir")
二、获取当前目录
getcwd()方法
getcwd()方法显示当前的工作目录。
语法:
os.getcwd()
注意,这里cwd是current working directory的缩写。
例2
import os
print os.getcwd()
运行结果:
E:\PythonProjects
三、改变目录
chdir()方法
可以用chdir()方法来改变当前的目录。chdir()方法需要的一个参数是你想设成当前目录的目录名称。
语法:
os.chdir("newdirname")
这里chdir是change directory的简写。
例3
import os
os.chdir("D:\\Doc")
print os.getcwd()
os.chdir("E:\\PythonProjects")
print os.getcwd()
运行结果:
D:\Doc
E:\PythonProjects
四、删除目录
rmdir()方法
rmdir()方法删除目录,目录名称以参数传递。
在删除这个目录之前,它的所有内容应该先被清除。
语法:
os.rmdir('dirname')
例4
import os
os.rmdir("testdir")
运行结果:
在E:\PythonProjects目录下执行这个程序,E:\PythonProjects\testdir被删除
异常
一、什么是异常
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
二、异常处理
捕捉异常可以使用try…except语句。
try…except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
如果你不想在异常发生时结束你的程序,只需在try里捕获它。
语法:
以下为简单的try....except...else的语法
try:
<语句> #运行别的代码
except <名字>:
<语句> #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句> #如果引发了'name'异常,获得附加的数据
else:
<语句> #如果没有异常发生
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
例1
try:
fh = open("mytest", "w")
fh.write("This is a file to test exception!")
except IOError:
print "Error: No file found or read file error!"
else:
print "Write cotent to file succeed!"
fh.close()
运行结果:
This is a file to test exception!
查看mytest文件中的内容:
This is a file to test exception
例2
将mytest文件的写权限去掉
chmod -w mytest
再次执行test.py,结果为
Error:
Error: No file found or read file error!
三、使用except而不带任何异常类型
你可以不带任何异常类型使用except
try:
正常的操作
......................
except:
发生异常,执行这块代码
......................
else:
如果没有异常执行这块代码
以上方式try…except语句捕获所有发生的异常。但这不是一个很好的方式,我们不能通过该程序识别出具体的异常信息。因为它捕获所有的异常。
四、try…except…finally语句
finally 中的代码无论是否发生异常都将被执行
例3:除0异常
try:
1 / 0
except Exception as e:
print "0 can not be divided!"
else:
print "No exception!"
finally:
print "Anyway, statement in finally block will be executed!"
运行结果:
0 can not be divided!
Anyway, statement in finally block will be executed!
五、raise触发异常
例4
#define function
def test_func( level ):
if level < 1:
raise Exception("Invalid level!", level)
try:
#invoke function
test_func(0)
except "any":
print 1
else:
print 2
finally:
print 3
运行结果:
3
Traceback (most recent call last):
File “test.py”, line 8, in <module>
test_func(0)
File “test.py”, line 4, in test_func
raise Exception(“Invalid level!”, level)
Exception: (‘Invalid level!’,0)
从运行结果可以看出,raise抛出异常后,except和else中的语句都没有被打印出来,但是finally中的语句被打印出来了。
面向对象
一、类与对象
例1
class Employee:
'Base class of employee'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def showInfo(self):
print "Name : ", self.name, ", Salary : ", self.salary
# Create the first instance
emp1 = Employee("Zhang San", 8000)
# Create the second instance
emp2 = Employee("Li Si", 15000)
emp1.showInfo()
emp2.showInfo()
print "Total Employee : %d" % Employee.empCount
运行结果:
Name : Zhang San, Salary : 8000
Name: Li Si, Salary : 15000
Total Employee : 2
分析:
(1)__init__
是构造函数。C++/Java中的构造函数名和类名一样,而Python的构造函数名为__init__
(2)self相当于C++或Java中的this, 是一个指针。当创建一个实例后,self指向该实例
(3)name和salary是实例变量,empCount是类变量
(4)C++/Java创建实例需要使用new关键字,Python不需要
(5)最后一行的第二个百分号,相当于C语言printf中的逗号
二、Python的内置类属性
__dict__ : 类的属性(包含一个字典,由类的数据属性组成)
__doc__ :类的文档字符串
__name__: 类名
__module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
__bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
例2
class Employee:
'Base class of employee'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def showInfo(self):
print "Name : ", self.name, ", Salary : ", self.salary
print "Employee.__doc__:", Employee.__doc__
print "Employee.__name__:", Employee.__name__
print "Employee.__module__:", Employee.__module__
print "Employee.__bases__:", Employee.__bases__
print "Employee.__dict__:", Employee.__dict__
运行结果:
Employee.__doc__: Base class of employee
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__:
{'showInfo': <function showInfo at 0x10a93caa0>,
'__module__': '__main__',
'empCount': 0,
'__doc__': ' Base class of employee ',
'__init__': <function __init__ at 0x10a939578>}
三、引用计数
Python 使用了引用计数这一技术来跟踪和回收垃圾。
在 Python 内部记录着所有使用中的对象各有多少引用。
一个内部跟踪变量,称为一个引用计数器。
当对象被创建时, 就创建了一个引用计数, 当这个对象不再需要时, 也就是说, 这个对象的引用计数变为0 时, 它被垃圾回收。但是回收不是"立即"的, 由解释器在适当的时机,将垃圾对象占用的内存空间回收。
例3
import sys
class Point:
def __init__( self, x = 0, y = 0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print class_name, "Destroyed!"
pt1 = Point()
print sys.getrefcount(pt1)
pt2 = pt1
print sys.getrefcount(pt1)
pt3 = pt2
print sys.getrefcount(pt1)
del pt3
print sys.getrefcount(pt1)
del pt2
print sys.getrefcount(pt1)
del pt1
运行结果:
2
3
4
3
2
Point Destroyed!
分析:
pt1 = Point(),等号右侧创建了一个对象,引用计数为1;等号左侧让引用pt1指向这个对象,引用计数加1变为2
pt2 = pt1,引用计数加1 变为3
pt3 = pt1,引用计数加1 变为4
del pt3,引用计数减1变为3
del pt2, 引用计数减1变为2
del pt1,引用计数减1,同时因为最初创建的对象没用引用指向他,对象会被释放,引用计数再减去1,变为0。析构函数__del__
被调用。
注意,因为引用计数为0,所以不能用 print sys.getrefcount(pt1)来查看引用计数。若查看会抛出异常。
继承
面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制。继承完全可以理解成类之间的类型和子类型关系。
需要注意的地方:继承语法 class 派生类名(基类名)://... 基类名写在括号里,基本类是在类定义的时候,在元组之中指明的。
在python中继承中的一些特点:
1:在继承中基类的构造(init()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用。
2:在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。区别在于类中调用普通函数时并不需要带上self参数
3:Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)。
如果在继承元组中列了一个以上的类,那么它就被称作"多重继承" 。
语法:
派生类的声明,与他们的父类类似,继承的基类列表跟在类名之后,如下所示:
class SubClassName (ParentClass1[, ParentClass2, ...]):
例1
class Parent:
number = 100
def __init__(self):
print "Invoke parent constructor method"
def parentMethod(self):
print 'Invoke parent method'
def setNumber(self, num):
self.number = num
def getNumber(self):
print "Parent's number :", self.number
class Child(Parent):
def __init__(self):
print "Invoke child constructor method"
def childMethod(self):
print 'Invoke child method'
c = Child()
c.childMethod()
c.parentMethod()
c.setNumber(200)
c.getNumber()
运行结果:
Invoke child constructor method
Invoke child method
Invoke parent method
Parent’s number : 200
python支持多继承:
class A: # 定义类 A
.....
class B: # 定义类 B
.....
class C(A, B): # 继承类 A 和 B
.....
与类相关的两个方法:
issubclass() -判断一个类是另一个类的子类或者子孙类,语法:issubclass(sub,sup)
isinstance(obj, Class) 如果obj是Class类的实例对象或者是一个Class子类的实例对象则返回true,否则返回false。
重写与重载
一、方法重写
重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!
如果你的父类方法的功能不能满足你的需求,你可以在子类重写你父类的方法。
例1
class Parent:
def myMethod(self):
print 'Invoke parent method'
class Child(Parent):
def myMethod(self):
print 'Invoke child method'
c = Child()
c.myMethod()
运行结果:
Invoke child method
下表列出了一些通用的功能,你可以在自己的类重写:
方法 | 描述 | 调用方式 |
---|---|---|
init ( self [,args...] ) | 构造函数,初始化对象 | obj = className(args) |
del( self ) | 析构方法, 删除对象 | del obj |
str( self ) | 用于将值转化为适于人阅读的形式 | str(obj) |
cmp ( self, x ) | 对象比较 | cmp(obj, x) |
二、运算符重载
Python的方法重载,可参考Java中的方法重载。
下面介绍一下运算符重载。
以加号为例,加号支持两个整数相加,两个浮点数相加,两个字符串相加
例2
a = 1
b = 2
print a + b
运行结果:
3
例3
a = “Hello “
b = “World!”
print a + b
运行结果:
Hello World!
现在假如有一个自定义的二维数据类型Num(x, y),咱们可能通过重载“+”运算符的方式实现:Num(x1, y1) + Num(x2, y2) = Num(x1 + x2, y1 + y2)
例4
class Num:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Num (%d, %d)' % (self.a, self.b)
def __add__(self, other):
return Num(self.a + other.a, self.b + other.b)
n1 = Num(5, 10)
n2 = Num(1, -2)
print n1 + n2
运行结果:
Num(6, 8)
注意 ,这里__add__
实现了Num的“+”功能,print方法会调用__str__
方法
类的属性与方法
(一)类的私有属性
__private_attr
:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs。
比如:self.__wife
(二)类的私有方法
__private_method:两个下划线开头,声明该方法为私有方法,不能在类的外部调用。
在类的内部调用方式为self.__private_methods
例1
class MyCounter:
__privateCount = 0
publicCount = 0
def count(self):
self.__privateCount += 1
self.publicCount += 1
print self.__privateCount
c = MyCounter()
c.count()
c.count()
print c.publicCount
print c.__privateCount
运行结果:
1
2
2
Traceback (most recent call last):
File "Count.py", line 17, in <module>
print counter.__privateCount
AttributeError: MyCounter instance has no attribute '__privateCount'
Python不允许实例化的类访问私有数据,但你可以使用 object._className__attrName 访问属性,将如下代码替换以上代码的最后一行代码:
print counter._MyCounter__privateCount
例2
class MyCounter:
__privateCount = 0
publicCount = 0
def count(self):
self.__privateCount += 1
self.publicCount += 1
print self.__privateCount
c = MyCounter()
c.count()
c.count()
print c.publicCount
print c._MyCounter__privateCount
运行结果:
1
2
2
2
(三)下划线说明
__foo__
: 定义的是特殊方法,一般是系统定义名字 ,类似__init__()
之类的。
_foo
: 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import *
__foo
: 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。
Tkinter图形界面编程
Tkinter 是 Python 的标准 GUI (Graphic User Interface)库。Python 使用 Tkinter 可以快速的创建 GUI 应用程序。
由于 Tkinter 内置到 python 的安装包中,只要安装好 Python 之后就能 import Tkinter 库。
例1:窗口
import Tkinter
top = Tkinter.Tk()
top.mainloop()
这里介绍一下mainloop。
mainloop就是进入到事件(消息)循环。一旦检测到事件,就刷新组件。
譬如你输入一个字符,就要立即在光标那个位置显示出来(前提是你选中了文本框,也就是鼠标在文本框这个图案的范围内单击过)。
又譬如你点击了浏览器的首页按钮,那么就要清除你浏览器里的全部部件,然后重新绘制主页的布局和内容。
运行结果:
例2:列表
from Tkinter import *
root = Tk()
computerLanguages = ['C','C++','Python','Java']
humanLanguages = ['Chinese','English','Spanish']
listbox1 = Listbox(root)
listbox2 = Listbox(root)
for item in computerLanguages:
listbox1.insert(0,item)
for item in humanLanguages:
listbox2.insert(0,item)
listbox1.pack()
listbox2.pack()
root.mainloop()
运行结果:
例3:按纽
from Tkinter import *
def clickButton():
print('hello button')
root = Tk()
Button(root, text='MyButton', command = clickButton).pack()
root.mainloop()
说明:
这里的clickButton是一个回调函数。当你点击按扭的时候,回调函数会被调用,在终端里打印出“hello button”。
运行结果:
Tkinter 组件
Tkinter的提供各种控件,如按钮,标签和文本框等。
目前有15种Tkinter控件。下表作了简单的介绍:
控件 | 描述 |
---|---|
Button | 按钮控件;在程序中显示按钮。 |
Canvas | 画布控件;显示图形元素如线条或文本 |
Checkbutton | 多选框控件;用于在程序中提供多项选择框 |
Entry | 输入控件;用于显示简单的文本内容 |
Frame | 框架控件;在屏幕上显示一个矩形区域,多用来作为容器 |
Label | 标签控件;可以显示文本和位图 |
Listbox | 列表框控件;在Listbox窗口小部件是用来显示一个字符串列表给用户 |
Menubutton | 菜单按钮控件,由于显示菜单项。 |
Menu | 菜单控件;显示菜单栏,下拉菜单和弹出菜单 |
Message | 消息控件;用来显示多行文本,与label比较类似 |
Radiobutton | 单选按钮控件;显示一个单选的按钮状态 |
Scale | 范围控件;显示一个数值刻度,为输出限定范围的数字区间 |
Scrollbar | 滚动条控件,当内容超过可视化区域时使用,如列表框。. |
Text | 文本控件;用于显示多行文本 |
Toplevel | 容器控件;用来提供一个单独的对话框,和Frame比较类似 |
Spinbox | 输入控件;与Entry类似,但是可以指定输入范围值 |
PanedWindow | 窗口布局管理的插件,可以包含一个或者多个子控件。 |
LabelFrame | 简单的容器控件。常用与复杂的窗口布局。 |
tkMessageBox | 用于显示你应用程序的消息框。 |
标准属性
标准属性也就是所有控件的共同属性,如大小,字体和颜色等。
属性 | 描述 |
---|---|
Dimension | 控件大小 |
Color | 控件颜色 |
Font | 控件字体 |
Anchor | 锚点 |
Relief | 控件样式 |
Bitmap | 位图 |
Cursor | 光标 |
几何管理
Tkinter控件有特定的几何状态管理方法,管理整个控件区域组织,一下是Tkinter公开的几何管理类:包、网格、位置
几何方法 | 描述 |
---|---|
pack() | 包装 |
grid() | 网格 |
place() | 位置 |
小朋友学Python(3)的更多相关文章
- 小朋友学Python(4)
Mac下安装Python 3 Mac系统会自带Python 2.7.x.安装Python 3时,不要卸载Python 2.7.x,因为有Mac系统有一些库会依赖于Python 2.7.x. 安装步骤: ...
- 小朋友学Python(1):Python简介与编程环境搭建
一.Python简介 不死Java,不朽C/C++,新贵Python. Python(英国发音:/ˈpaɪθən/ 美国发音:/ˈpaɪθɑːn/), 是一种面向对象的解释型计算机程序设计语言,由荷兰 ...
- 小朋友学Python(2)
本节学习python的第一个程序:输出“Hello World!”.咱们用两种方法实现 方法(一) 进入python环境,直接使用print方法 hello world.png 方法(二) 先编程 ...
- 【Python五篇慢慢弹】快速上手学python
快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...
- <-0基础学python.第一课->
初衷:我电脑里面的歌曲很久没换了,我想听一下新的歌曲,把他们下载下来听,比如某个榜单的,但是一首一首的点击下载另存为真的很恶心 所以我想有没有办法通过程序的方式来实现,结果还真的有,而且网上已经有有人 ...
- 学Python后到底能干什么?
Python是一种什么语言? Python是一种计算机程序设计语言.你可能已经听说过很多种流行的编程语言,比如非常难学的C语言,非常流行的Java语言,适合初学者的Basic语言,适合网页编程的Jav ...
- 关于智普 - 千人免费学|Python培训|国内最权威python培训|html5
关于智普 - 千人免费学|Python培训|国内最权威python培训|html5 智普教育隶属于北京顶嵌开源科技有限公司,成立于2008年. 智普开源是基于Linux系统的互联网开源学习平台,讲求务 ...
- [置顶] 和孩子们一起学Python编程
1. 推荐书名 Computer Programming for Kids and Other Beginners in Python, 4Ed.pdf 中文译名:<和孩子们一起学Pyt ...
- 简学Python第二章__巧学数据结构文件操作
#cnblogs_post_body h2 { background: linear-gradient(to bottom, #18c0ff 0%,#0c7eff 100%); color: #fff ...
随机推荐
- 1.1.4 A+B for Input-Output Practice (V)
A+B for Input-Output Practice (V) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K ...
- 关于XCode 的agvtool命令行
简介:用agvtool如何来自动更新版本号和bulid version agvtool是一个命令行工具,允许你自动递增到下一个最高的数量或具体的数字这些数字.本文档提供了更新您的构建和版本号码使用 ...
- Java项目体验
1. JAVA开发环境安装和配置 a) 下载JDK(Java Development Kit) b) 安装JDK. JRE(Java Runtime ...
- Webform---母版页(Master Pages)
母版页(Master Pages)为网站内的其他页面提供模版. Master Page 使您有能力为 web 应用程序中的所有页面(或页面组)创建一致的外观和行为. Master Page 为其他页面 ...
- C#写的window服务内存溢出
浅谈c#垃圾回收机制(GC) 写了一个window服务,循环更新sqlite记录,内存一点点稳步增长.三天后,内存溢出.于是,我从自己的代码入手,查找到底哪儿占用内存释放不掉,最终明确是调用servi ...
- java打jar包的几种方式详解
经常会头疼于一个jar包是如何制作的,包括maven的打包方式,springboot的打jar包的原理,jar包稍稍有错误就会完全无法运行.在网上折腾了很久终于有些思路和步骤,在这里做个笔记 本文目录 ...
- TCC(Tiny C Compiler)介绍
TCC是一个超小.超快的标准C语言编译器.她可以从这里(http://bellard.org/tcc/)下载到:注意,要下载http://download.savannah.nongnu.org/re ...
- mibox connections
tcp 0 0 :::52549 :::* LISTEN 4398/net.myvst.v2:mt ...
- oracle单表选择率(selectivity)——计算执行计划的基数
CBO优化器是基于对当前经过特定测试的数据集中预期的行比率估计来计算基数的.此处的行数之比是一个数值,称为选择率(selectivity).得到选择率之后,将其与输入行数进行简单相乘既可得到基数. 在 ...
- spring boot 项目文件结构
启动类建议放在RootPackage的原因: 根据SpringBoot的内置实现,Spring默认从@ComponentScan注解所在的位置开始向后扫描,也就是说,只要我们将组件放在启动类所在的Ro ...