开发
python中的基本数据类型有:布尔值、数字、字符串、元组、字典。
开发语言
高级语言:Python、Java 、PHP、C#、GO、ruby、C++……
低级语言:C语言、汇编
语言之间的对比
PHP类:适用于写网页,局限性
Python Java:即可写网页,也可以写后台程序
Pyhont执行效率低,开发效率高
Java执行效率高,开发效率低
Python种类
JPython
IRonPython
JavaScriptPython
RubyPthon
……
pypy 这是用CPython开发大的Python
安装:
Python安装在OS上
执行操作:
洗衣歌文件中按照python的规则写,将文件交给python软件,读取文件中都内容,然后进行换行 和执行,最终获取结果。
Python软件 --> Python解释器(内存管理)
下载:
Python3 在继续更新
Python2 再继续更新
基本数据类型
关键字解释
常用方法中出现的参数名解释:
数据类型:
bool:布尔类
int:整数类
list:列表类
tuple:组员类
dict:字典类
自定义表格参数名称说明:
ele:列表元素
var:变量,各种数据类型的变量
int1:整数对象1
int2:整数对象2
ch1:字符1
ch2:字符2
str1:字符串对象1
str2:字符串对象3
list1:列表对象1
list2:列表对象2
tuple1:组员对象1
tuple2:组员对象2
dict1:字典对象1
dict2:字典对象2
key1:字典键名1
key2:字典键名2
方法、函数原型内参说明:
value:值
index:索引值
iterable:可迭代对象
bool 类
bool类说明
ls = [12, 4.5, "fjdk", [4, "fd"], True]
list类是一种类,而ls属于list对象。
常用方法中出现的参数名解释
bool对象可调用方法
方法原型 | 使用举例 | 参数说明 |
---|---|---|
def append(self, p_object) | list.append(p_object) | 在原来列表list后进行追加元素p_object |
int 类
int():
int:整形
在python3里面所有的整形都是int类型
int对象可调用方法
方法原型 | 简介 | 使用举例 | 参数说明 |
---|---|---|---|
def int(tar) | 转换为整形 | value = int(tar) | 将tar数据类型转换为int类型并返回给value |
def int(tar, base = num) | 进制转换 | value = int(tar, base = 10) | 将tar数据类型转换以十进制格式转化为int类型并返回给value |
def bit_lenth(self) | 数据占位长 | value = int.append() | 返回int当前值至少需要多少个bit为表示 |
扩展函数:type(var);函数说明:判断var的数据类型,并以字符串的形式放回var的数据类型。
str 类
str对象可调用方法
方法原型 | 简介 | 使用举例 | 参数说明 |
---|---|---|---|
def capitalize(self) | 首字母大写 | str2 = str1.capitalize() | 将原字符串首字母大写然后进行返回 |
def lower(self) | 转换小写 | str2 =str1.lower() | 将字符str1中的内容以小写的形式返回给str2 |
def casefold() | 转换小写 | str2 =str1.lower() | 将str1转换为小写,包括一些特殊字符 |
def center(self, widh, fillchar=None) | 设置宽度居中 | str1.center(widh) | 将字符str1以with的宽度显示,其中str1进行居中,边框默认应用空格填充 |
def ljust(self, width, fillchar=None) | 设置宽度居左 | str1.ljust(widh) | 将字符str1以with的宽度显示,其中str1进行居左,右边默认应用空格填充 |
def rjust(self, width, fillchar=None) | 设置宽度居右 | str1.rjust(widh) | 将字符str1以with的宽度显示,其中str1进行居右,左边默认应用空格填充 |
def zfill(self, width) | 设置宽度居右 | str1.rjust(widh) | 将字符str1以with的宽度显示,其中str1进行居右,左边默认应用0填充 |
def count(self, sub, start=None, end=Node) | 统计 | value = str1.count(sub) | 统计str1中sub出现的次数 |
def encode(self, encoding=‘utf-8’, errors=‘strict’) | 编码 | str2 = str1.encode(‘utf-8’) | 将字符串str1转换为utf-8编码,返回到str2 |
def decode(self, encoding=‘utf-8’, errors=‘strict’) | 解码 | str2 = str1.decode() | 将str2字符串的编码格式转换为默认编码格式,将转换后的编码返回到str1 |
def startswith(self, suffix, start=None, end=None) | 判断起始 | value = str1.endswith(str2) | 判断str1是否已str2开始,是为True否则为False |
def endswith(self, suffix, start=None, end=None) | 判断结尾 | value = str1.endswith(str2) | 判断str1是否已str2结尾,是为True否则为False |
def find(self, sub, start=None, end=None) | 寻找 | value = str1.find(sub) | 返回判断字符串str1中sub元素首次出现的下标位置, 没有返回-1 |
def expandtabs(self, tabsize=8) | 格式化转义字符 | str1.expandtabs(tabsize) | 将原字符串str1以tabsize个字符为分割,遇到\t时以空格补齐tabsize-分割后字符串个数 |
def format(*args, **kwargs) | 替换占位符 | str3 = str1.format(placeholder = str2) | 将str1中的占位符名为placeholder替换为字符串str,并将替换后的结果返回给str3 |
def format_amp(self, mapping) | 做占位符 | str2 = str1.format_map(“0”:str3, “2”:str4, …) | 与format()使用相似 |
def index(self, sub, start=None, end=None) | 查找 | value = str1.index(sub) | 返回判断字符串str1中sub元素首次出现的下标位置, 没有直接报错。很少使用 |
def isalnum(self) | 数字字母判断 | vlaue = str1.isalnum() | 判断字符串str1是否为纯数字字母组成,包含其他字符返回False |
def isalpha(self) | 是否是字母 | value = str1.sialpha() | 判断字符串str1是否为纯字母或汉字,包含其他字符返回False否则返回True |
def isdecimal(self) | 判断是否是数字 | value = str1.isdecimal() | 判断字符串str1是否是数字,全部是数字返回True否则返回False |
def isdigit(self) | 数字判断 | value = str1.isdigit() | 判断字符串str1是否是数字,全部是数字返回True否则返回False,isdigit()能够判断特殊数字如:① |
def isidentifier(self) | 标识符 | value = str1.isidentifier() | 判断字符串str1中的内容是否符合变量命名规则,即标识符,满足返回True不满足返回False |
def islowre(self) | 小写判断 | value = str1.islower() | 判断字符串str1所有字符是否是小写,是小写返回Turue,不是小写返回False |
def lowre(self) | 小写准换 | str2 = str1.lower() | 将字符串str1中的所有字符转换为小写然后返回到str2 |
def isupper(self) | 大写判断 | value = str1.isupper() | 判断字符串str1中所有字符是否是大写,是大写返回Turue,不是大写返回False |
def upper(self) | 大写转换 | str2 = str1.upper() | 将字符串str1中的所有字符串转换为小写然后返回到str2 |
def isnumeric(self) | 数字判断 | value = str1.isnumeric() | 判断字符串str1是否是数字,全部是数字返回True否则返回False ,isnumeric()能够判断特殊数字如:①、二 |
def isprintable(self) | 是否存在不可显示字符 | value = str1.isprintable() | 判断字符串中是否包含不可见字符(\r、\n…)如果包含不可见字符返回False,不包含返回True |
def isspace(self) | 是否是空格 | value = str1.isspace() | 判断字符串str1是否问纯空格,是空格返回True,不是空格返回False |
def istitle(self) | 标题判断 | value = str1.istitle() | 判断str1是否是标题返回标题:是标题返回True,不是字符串返回False;标题:字符串中所有单词首字母大写 |
def title(self) | 设置为标题 | str2 = str1.title() | 将str1中的字符串转换为标题的形式然后返回到str2 |
def join(self, iterable) | 字符间隙填充 | str2 = ‘_’.join(str1) | 将字符串str1中的相邻字符串之间增加一个 '_'进行拼接,然后返回到str2 |
def strip(self, chars=None) | 去除两边 | str2 = str1.strip() | 将str1中内容与chars相同子集删除,然后返回到str2 |
def lstrip(self, chars=None) | 去除左边 | str2 = str1.lstrip() | 将str1中的内容左边去除chars指定字符,然后返回到str2;默认去除 空格、\n、\t |
def rstrip(self, chars=None) | 去除右边 | str2 = str1.rstrip() | 将str1中的内容右边去除chars指定字符,然后返回到str2;默认去除 空格、\n、\t |
def maketrans(self, *args, **kwargs) | 建立对应关系 | ele = str.maketrans(str1, str2) | 将字符串str1与str2对应字符建立对应关系 ,与方法translate()配合使用 |
def translate(self, table) | 对应字符替换 | str2 = str1.translate(trans) | 将str1字符串中的内容按照trans的对应关系进行替换 |
def partition(self, sep) | 字符串分割 | ele = str1.partition(ch) | 以第一字符ch进行将str1进行分割 |
def lpartition(self, sep) | |||
def rpartition(self, sep) | |||
def split(self, sep, maxsplit) | 分割字符串 | ele = str1.split(sep) | 将字符串str1以 sep进行分割,而str1中的sep也同时删除 |
def rplit(self, sep, maxsplit) | |||
def splitlines(self, keepends=None) | 以空格分割 | ele = str1.splitlines() | 将字符串str1以空格为分割进行分割 |
def swapcase(self) | 大小写转换 | str2 = str1.swapcase() | 将字符串str1的内容大写转换为小写,小写转换为大写然后返回到str2 |
def replace(self, old, new, count) | 字符串替换 | str2 = str1.replace(str3, str4) | 将字符串str1中包含与str3相等的字符串替换成str4,然后染回到str2 |
常用的6个基本字符串处理函数:
join、split、find、strip、upper、lower、replace
字符串格式化
字符串个格式化主要应用形式有:% 和 format()
str1 = “i am %s my hobby is alex” %“aaaa”
字符串的格式化用 %
当传入个多格式化数值的时候用:%()
格式化传入的符号有:%s、%d、%f、%()、%[]
() 传入字典键名
Python格式化字符串代替符号及其含义
符号 | 说明 |
---|---|
%c | 格式化字符及其ASCII |
%s | 格式化字符串 |
%d | 格式化整数 |
%u | 格式化无符号整数 |
%o | 格式化无符号八进制 |
%x | 格式化无符号十六进制 |
%X | 格式化无符号十六进制(大写) |
%f | 格式化浮点数,可指定小数点后的精度 |
%e | 用科学计数法格式化浮点数 |
%E | 作用同%e,用科学计数法格式化浮点数 |
%g | 根据值得大小决定使用%f或%e |
%G | 作用同%g,根据值得大小决定使用%f或%e |
%p | 用十六进制数格式化变量的地址 |
%% | 格式化% |
Python的转义字符及其含义
符号 | 说明 |
---|---|
’ | 单引号 |
" | 双引号 |
\a | 发出系统响铃声 |
\b | 退格符 |
\n | 换行符 |
\t | 横向制表符 |
\v | 纵向制表符 |
\r | 回车符 |
\f | 换页符 |
\o | 八进制数代表的字符 |
\x | 十六进制代表的字符 |
\000 | 终止符,\000后的字符串全部忽略 |
\ | 输出\ |
字符串格式化应用示例
msg1 = 'i am %s my hobby is %s' %(str1 , str2) #拼接多个字符串
msg2 = 'i am %s my hobby is %3' %(str1 , str2) #拼接字符串和整数
msg3 = "float = %f" % float1 #格式化浮点数
msg4 = 'i am %(name)s age %(age)d' % {"name":"alex", "age":18} #传入字典
list 列表
list
1.列表的格式
2.列表可以嵌套任何数据类型
3.列表的索引和修改可以通过下标、分割方式
4.可以通过for、while进行逐一访问
5.可以通过切片的方式进行索引和修改
6.列表的删除del
7. in操作,列表元素索引通过 逗号(,)进行分割
8. 字符串转换成列表
9. 列表转换为字符串
10.当列表中只包含字符的时候可以使用:st = “”.join(ls)。如果列表中既有字符串又有数字是需使用for循环。
列表内可是字符、字符串、数字、bool等数据类型,链表内部还可以嵌套链表
列表的索引可以通过列表下标索引,索引下标从0开始
ls = [15, 126.5, 'd', "hello", [12, 45, "fdfa"], False] #创建列表
print(ls[0]) #索引ls列表的第0个元素
print(ls) #输出ls列表所有元素
ls[4] = "Hello world" #通过下标索引方式进行修改
ls[1:3] = [100.5, 'c'] #通过切片方式进行修改
del ls[1:3] #通过切片的方式进行对列表元素的删除
print(15 in ls) #通过in进行判断15是否存在列表ls当中
s = "Hello"
new_ls = list(s) #将字符串s转换为列表
list 类
list类说明
ls = [12, 4.5, "fjdk", [4, "fd"], True]
list类是一种类,而ls属于list对象。
list类可调用的方法
方法原型 | 简述 | 使用举例 | 参数说明 |
---|---|---|---|
def append(self, p_object) | 追加元素 | list.append(p_object) | 在原来列表list后进行追加元素p_object |
def clear(self) | 清空列表 | list.clear() | 清空列表list |
def copy(self) | 拷贝 | list_new = list.copy() | 拷贝,浅拷贝 |
def count(self, value) | 统计相同元素 | int = list.count(value) | 返回list列表中与value元素相同的个数 |
def extend(self, iterable) | 追加元素 | list.extend(new_list) | 将new_list扩展到list后面,iterable参数为可迭代对象 |
def index(self, value, start=None, stop=None) | 搜索元素 | num = list.index(value) | 返回列表list中元素value首次出现的下标 ,从左到右查询 |
def insert(self, index, p_object) | 插入元素 | list.insert(index, p_object) | index:插入元素下标, p_object:要插入的元素。在制定位置插入元素 |
def pop(self, index=None) | 移除元素 | ele = list.pop() | 默认删除列表list最后的元素,并将删除元素返回到ele, index:删除索引元素 |
def remove(self, value) | 移除元素 | list.remove(value) | 删除列表中的第一次出现于value值相同的元素 |
def reverse(self) | 列表反制 | list.reverse() | 将当前列表list进行翻转操作 |
def sort(self, key=None, reverse=False) | 列表排序 | list.sort() | 对原列表list进行排序,默认为升序 |
删除列表元素的方式有:
del list[index]、list.pop()、list.remove(value)、list.clear()
tuple 元组
列表:li = [1, 2, 3, 4],列表对应的对象是list
元组:tu = (1, 2, 3, 4),元组对应的对象是tuple
列表与元组从定义上就是方括号变成圆括号的区别,其实元组就是对列表的一个二次加工,他把列表加工成了元素不能被修改,并且不能删除,能查看。
一般在写元组的时候在右边圆括号前面添加一个逗号(,)。
元组可以被for循环,元组也是可迭代对象。
字符串、列表、元组之间可以相互转换。
总结:
- 元组书写格式用圆括号
- 可以用索引的方式访问
- 元组创建后,一级元素不能被删除/修改 /增加
- 元组可以进行切片
- 元组是可迭代对象,也可以被for循环
- 可迭代对象之间可以进行转化
- 元组也是***有序***的
元组应用场合:
元组什么时候定义元组呢,当定义的数组以后不能更改的时候可以使用元组。
元组应用示例:
# 字符串、列表、元组之间的相互转换
#------------------------------------------------------------
str1 = "dghglk46652" #创建字符串对象str1
list1 = ["fda", 456, "fdfh"] #创建列别表对象list1
tuple1 = ("fdgfk", "jgnbn",) #创建元组对象tuple1
str2 = str(list1) #将列表准换为字符串
str3 = str(tuple1) #将元组转换为字符串
list2 = list(str1) #将字符串转换为列表
list3 = list(tuple1) #将元组转换为字符串
tuple2 = tuple(str1) #将字符串转换为元组
tuple3 = tuple(list1) #将列表转换为元组
# 元组的读取与修改
#------------------------------------------------------------
tuplt1 = (154, "aaa", ["bbbb", 15, ["ccc"], 1445],)
value1 = tuple1[0] #获取元组一级元素
value2 = tuple1[2][0] #获取元组二级元素
#tuple1[1] = "dfjk" X #语句错误,元组第一级元组不能被修改
tuple1[2][1] = 46 #修改元组的第二级元素 ,列表的元素能够被修改
tuple类可调用的方法
方法原型 | 简述 | 使用举例 | 参数说明 |
---|---|---|---|
def count(self, value) | 统计value | value1 = tuple1.count(value) | 统计元组tuple1中value1出现的次数返回发到value |
def index(self, value, start=None, end=None) | 获取位置 | value1 = tuple1.index(value) | 统计元组tuple1中value1首次出现的位置返回发到value |
dict 字典
创建一个字典: info = {“key1”:“value1”, “key2”:“value2”}
字典中以逗号进行分割,上面的列子创建了两个值,“d1”:"value1"的组合称为 键值对 , 对应 键名:键值。
总结:
- 字典书写格式用花括号 {}。
- 字典的元素是一个键值对。
- 字典的元素以逗号进行分割。
- 字典的键不能使用列表/字典,字典的值可以是任何数据类型。
- 字典的键名不要重复,如果发生重复使用最后一次定义的键名。
- 字典是 无序 存放的。
- 字典的查询和修改通过键key进行索引。
- 元组也是有序的。
- 字典可以通过 del 进行删除元素。
- 字典允许通过for循环进行遍历
字典的应用示例
# 创建字典
#------------------------------------------------------------
info = {
1:"aaaaaa"
"key1":"bbbbb"
False:"cccccc" #用布尔值做为字典的key
# [11, 22]:1122 #字典的key不能使用列表
# {key1:44}:45 #字典的key不能使用字典
"key2":[45, 687, "dddd"] #
"key3":{True, 123, "elcx", [], (), {}}
"key4":(1, 2, 3, 4)
}
# 字典的访问和修改
#------------------------------------------------------------
value = info["key1"] #获取字典键为key1的元素数据
print(value)
value = info["key2"][0] #获取字典键为key2元素数据为列表第一个元素
print(key2)
# 字典的遍历
#------------------------------------------------------------
#用法1获取键名
for item in info: #输出字典的键名key
print(item)
#用法2获取键名
for item in info.keys(): #输出字典的键名key
print(item)
#用法获取键值
for item in info.values(): #输出字典的所有value
print(item)
#用法4获取键名和键值
for k, v in info.items(): #输出字典的key和value
print(k + ":" + v)
dict类可调用的方法
方法原型 | 简述 | 使用举例 | 参数说明 |
---|---|---|---|
def clear(self) | 清空元素 | dict1.clear() | 清空字典ditc1 |
def copy(self) | 拷贝 | dict2 = dict1.copy() | 将字典dict1中的内容拷贝到字典dict2, copy为浅拷贝 |
def formkeys(**args, **kwargs) | 创建字典 | dict1 = dict.formkeys([12, “key1”, “key2”]) | **args为创建键名列表,默认创建键值默认为None |
def get(self, k, d=None) | 读取键值 | value = dict1.get(key1) | 返回查询字典dict1的键名为key1的键值,如果键名不存在默认返回None |
def keys(self) | 遍历键名 | for key in dict1.items(): | 遍历字典dict1的键名 |
def values(self) | 遍历键值 | for value in dict1.items(): | 遍历字典dict1的键值 |
def items(self) | 遍历元素 | for k, v in dict1.items(): | 遍历字典dict1的键名:键值 |
def pop(self, k, d=None) | 删除元素 | value = dict1.pop(key1) | 寻找字典dict1中的键名并删除键名元素,将删除键名元素的键值返回给value |
def popitem(self) | 删除元素 | k ,v = dict1.popitem() | 随机删除字典dict1中的一个元素,将返回删除元素的键名和键值分别返回到k和v,删除键值不存在默认返回None |
def setdefault(self, k, d=None) | 设置元素 | key2 = ditc1.defaule(key1, value) | 如果字典dict1中的键值不存在返回将添加键值key1,字典dict1中存在该键名将返回键值 |
def update(sef, E=None ,**F) | 更新 | dict1.update(key1:‘121’, key2:45) | 更新字典dict1,若字典存在键名则设置键值,如果字典中不存在键则创建键名并设置键值 |
集合
集合定义:有不同的元素组成的集合,集合中是一组无序排列的可hash值,可以可以作为字典的key
集合特性:
1.无序
2.不可变
集合的使用
#-----------------------------
# 创建集合
s1 = {1,2,3,4,5,6} #创建集合
s2 = set([1,2,3,4,5,6]) #创建集合
s2.add("jk") #向集合中添加元素
s1.clear() #清空集合
集合类可调用的方法
方法原型 | 简述 | 使用举例 | 参数说明 |
---|---|---|---|
def add(self, *args ,**kwargs) | 添加元素 | s1.add(“jk”) | 向集合1中添加元素 |
def clear(self, *args, **kwargs) | 清空集合 | s1.clear() | 将集合s1中的元素清空 |
def copy(self, *args, **kwargs) | 拷贝集合 | 上 = s1.copy() | 将集合s1复制到集合s2中 |
def pop(self, *args, **kwargs) | 删除元素 | s1.pop() | 删除集合s1中的一个元素 |
def remove(self, *args, **kwargs) | 删除元素 | s1.remove(get1) | 将集集合s1中的与get1值相等的元素删除,删除元素不存在报错 |
def discaed(self, *args, **kwargs) | 删除元素 | s1.discaes(get1) | 与remove相似,删除元素不存在不报错 |
def intersection(self, other) | 交集 | s3 = s1.intersection(s2) | 获取集合s1 |
def union(self, other) | 并集 | s3 = s1.union(s2) | 求集合s1与集合s2的并集,把结果返回给s3;与s1 l s2结果相等 |
def fifference(self, other) | 差集 | s3 = s1.difference(s2) | 返回集合s1减去集合s1与s2的交集,与s3 = s1-s2结果相同 |
def symmetric_difference(self, other) | 交叉补集 | s3 = s1.symmetric_difference(s2) | 返回集合s1、s2的并集减去s1、s2的交集,把计算单额结果返回大s3,与s3 = s1^s2结果相同 |
def difference_update(self, other) | 交叉补集 | s1.difference_update(s2) | 返回集合s1、s2的并集减去s1、s2的交集,把计算的结果直接更新到s1中,与s1 = s1^s2结果相同 |
def isdisjoint(self, other) | 判断交集空 | value = s1.intersection(s2) | 判断集合s1与s2的交集是否为空,为空返回True,不为空返回False |
def issubset(self, other) | 判断子集 | value s1.issubset(s2) | 判断集合s1是否为集合s2的子集,是子集返回True, 不是子集返回False |
def isupperset(self, other) | 判断父集 | value s1.isupperset(s2) | 判断集合s1是否为集合s2的父,是父集返回True, 不是父集返回False |
不可变集合
frozenset()
frozenset函数创建的集合不能被修改、追加、删除。
s1 = frozenset([“fdkls”, 154])
正则表达式
正则表达式用于搜索、替换、和解析字符串。正则表达式的功能强大,使用非常灵活。使用正则表达式需要遵循一定的语法规则,用来编写一些裸机验证非常方便,例如电子邮件的验证。Python提供了re模块实现正则表达式的验证。
正则表达式的特殊字符
符号 | 说明 |
---|---|
^ | 正则表达式的开始字符 |
$ | 正则表达式的结束字符 |
\w | 匹配字母、数字、下划线 |
\W | 匹配不是字母、数字、下划线的字符 |
\s | 匹配空白字符 |
\S | 匹配不是空白的字符 |
\d | 匹配数字 |
\D | 匹配非数字的字符 |
\b | 匹配单词的开始和结束 |
\B | 匹配不是单词开始和结束的位置 |
. | 匹配任意字符,包括汉字 |
[m] | 匹配单个字符串 |
[m1m2… n] | 匹配多个字符串 |
m-n | 匹配m到n区间内的数组、字母 |
[ ^m] | 匹配除m意外的字符串 |
() | 对正则表达式进行分组,一对圆括号表示一组 |
正则表达式中的常用限定符
符号 | 说明 |
---|---|
* | 匹配零次或多次 |
+ | 匹配一次或多次 |
? | 匹配一次或零次 |
{m} | 重复m次 |
{m,n} | 重复m到n次。其中n可以省略,表示到任意次 |
函数
函数定义
1. 函数定义格式:
def function(value):
"Create a function..."
value *= 2
return value //函数返回值
格式说明:
def:定义函数的关键字;
function:用户自定义函数名;
():用户传入函数参数;
"Create a function...":函数描述(可写可不写,建议使用添加函数描述,方便以后对知道函数作用);
return:返回或传出数据;
2. 总结使用函数的好处:
- 提高代码的使用效率,代码重用;
- 保持一致性,易维护;
- 可扩展性好。
3. 函数与过程
函数就就是上面函数定义格式类型方式,而过程就是函数中 没有return 语句,过程也是函数的一种形式。在函数中只要遇到return语句函数接结束并返回,一个函数中可以有多个return语句。
4. 函数的返回值
过程的返回值为None,函数可以返回各种数据类型,在返回多种数据类型的时候以 元组tuple 的形式进行返回。
5. 函数的参数
- 形参 只有在被调用时才分配内存,在调用结束时,即可释放所分配的内存单元。因此,形参只在函数内部有效。函数调用借宿返回主调用函数后则不能再使用该形参变量;
- 实参 可以是常量、变量、表达式、函数等,无论实参是何种数据的变量,在进行函数调用时,他们必须有确定的值,以便吧这些值传递给形参。因此预先用赋值,输入等办法是形参获得确定值;
- 位置参数 必须一一对应,不可缺少参数也不可多参数;
- 关键字参数 无需一一对应,不可缺少参数也不可多;
- 位子参数和关键字参数混合使用时,位子参数必须在关键字参数左边;
- 默认参数 可以在用户使用的时候设置默认参数值;
- 可变长参数,*args 接收的是一个 列表 或 元组 , **kwargs 是传入字典。
6. 局部变量和全局变量
- 全局变量 在程序开始是顶头定义的变量,全局变量可以被整个程序调用;
- 局部变量 是在一个函数中定义或一个表达式中定义的变量;
- global 在函数中调用外部的全局变量;
- 在python3变量名命名规则,全局变量全部用大写,局部变量用小写。
7. 函数的递归
函数的递归就是函数自己调用函数自己。
递归特性:
- 必须有一个明确的结束条件;
- 每次进入更深次递归时,问题规模比上一次递归都应有所减少;
- 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用时通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会建一层栈帧。由于栈的大小是有限的,所以递归调用次数过多会导致栈溢出)。
8.匿名函数
lambda
lambda函数用于创建一个匿名函数,函数名未知和标识符进行绑定。使用lambda函数返回一些简单的运算结果
lambda函数格式:
lambda 形参1,形参2… : 表达式
应用实例:
x = 5
y = 6
sum = lambda x, y :x*y
print(sum) #输出结果为20
9.函数式编程
编程的方法论:
面向过程
函数式编程
面向对象
函数式编程:函数式 = 编程语言定义的函数+数学意义的函数
在函数式编程中定义函数过程中不进行创建变量,不修改变量
高阶函数:
- 函数接收的参数是一个函数名。
- 返回值中包含函数。
应用示例:
NAMR = "xiaoming0000" #定义全局变量
def calc1(x, y, z): #定义函数calc1函数
return x+y+z # x、y、z就是形参
def calc2(x, y, z=0): #定义带默认参数calc2函数
return x+y+z
def calc3(x, *args): #定可变长参数类型函数
return x
def calc4(x, *args, **kwargs): #*args(列表)必须放在**kwargs(字典)右边
return x
def print_name():
global NAME
NAME = "xiaoming0001"
value1 = calc1(1, 2, 3) #使用位置参数调用函数
value2 = calc1(y=1, x=2, z=3) #使用关键字参数调用函数
value3 = calc2(1, 2) #使用默认参数调用带默认参数函数
func = lambda x:x*x #创建匿名函数
print(func(5)) #调用匿名函数
内置函数
range()
range()函数返回的是一个可迭代对象,在使用的时候不会打印创建的对象,range()函数返回的可迭代对象,返回类型是一个列表。range()函数在于for循环配合使用的时候会创建列表。
#-----------------------------
# 用法1:默认从0开始创建,创建到指定数值
value1 = range(50) #默认从0开始创建49
print(value1)
for i in value1:
print(i)
#-------------------------------
# 用法2:从 起始 值创建到 终止 值
value2 = range(10, 50) #从10开始创建到49
for i in value2:
print(i)
#-------------------------------
# 用法3:从 起始 值创建到 终止 值没间隔 多少个数值进行创建
value3 = range(1, 20, 3) #增值:从1开始每间隔3个数值创建一个知道大于终止值为止, 3也成为步长
for i in value3:
print(i)
#-------------------------------
# 用法4:从 起始 值创建到 终止 值没间隔 多少个数值进行创建
value3 = range(20, 1, -3) #减值:从20开始每间隔3个数值创建一个知道大于终止值为止, -3也成为步长
for i in value3:
print(i)
for
for循环9*9乘法表
for i in range(1, 10):
str1 = ""
for j in range(1, 10): #嵌套for循环
if j > i:
break;
str1 += str(j) + "*" + str(i) + "=" + str(i*j) + '\t'
print(str1)
enumerate
函数功能:将参数列表的下标和值组成一个元组,返回参数地址;
函数参数:参数为一个列表或元组;
应用示例
list1 = [1, 2, 3, 5, 'fd'] #创建列表
print(enumerate(list1)) #输出enumerate函数返回的结果
print(list(enumerate(list1))) #输出:[(0, 1), (1, 2), (2, 3), (3, 5), (4, 'fd')]
result = list(enumerate(list1)) #将enumerate函数的额返回结果转换为列表
#-------------------------------
# 以列表的形式遍历list1的下标和下标元素
for i in result:
print("list[%d] = %s" %(i[0], i[1]))
#-------------------------------
# 使用enumerate函数遍历list1列表的下标和下标元素
for index, value in enumerate(list1):
print("list[%d] = %s" %(index, value))
map
map 函数第一个参数是处理的方法,第二参数是一个可迭代对象。
函数作用将可迭代对象中的每个元素按照第一个参数的处理方法进行返回。
map函数是对原可迭代对象进行处理,返回还是原可迭代对象。
应用示例:
def add_one(num): #用户自定义处理函数
return num+1
list1 = [1, 5, 48, 25]
map(lambda x:x+1, list1)
print(list(list1))
map(add_one, list1)
print(list(list1))
filter
filter 函数第一个参数是处理的方法,第二参数是一个可迭代对象。
函数作用:将可迭代对象中的元素按照第一个参数的方法进行做相应的处理, 处理结果为真则输出元素,为假则筛除元素。
filter函数处理原可迭代对象,移除被筛选元素,返回处理后新的可迭代对象。
应用示例:
def del_starts(ls): #用户自定义处理函数
return ls.startswith("ls") #该行为判断元素是否以字符串“ls”开头,如果是返回真TRUE,如果不是返回假FALSE
list1 = ["ls_1", "ls_2", "sl_3", "ls_4"]
print(list1)
print(list(filter(lambda x:x.startswith("ls"), list1)))
list1 = ["ls_1", "ls_2", "sl_3", "ls_4"]
print(list(filter(del_starts, list1)))
reduce
使用reduce函数需添加 from functools import reduce
reduce 函数第一个参数是处理的方法,第二参数是一个可迭代对象。
函数功能:将可迭代对象中的每个元素进行做运算,返回做运算的值。
应用示例:
from functools import reduce
list1 = [1, 4, 5, 50]
print(list1)
print(reduce(lambda x,y:x*y, list1)) #输出结果1000,运算过程1*4*5*50 = 1000
print(reduce(lambda x,y:x*y, list1, 4) #输出结果4000,运算过程1*4*5*50*4 = 4000
len
len() 返回长度
应用实例:
str1 = 'hello'
print(len(str1))
abs
abs为取绝对值函数
应用实例:
print(abs(1))
print(abs(-1))
all
all 函数将元素中的每个元素与True进行与运算,如果所有元素为True为返回结果为True。
应用实例:
print(all([1, 2, '1'])) #返回 True
print(all([1, 2, None])) #返回 False
print(all([1, 2, False])) #返回 False
print(all([1, 2, []])) #返回 False
any
any 函数与all相反
应用实例:
print(any([1, 2, '1'])) #返回 False
print(any([1, 2, None])) #返回 True
print(any([1, 2, False])) #返回 True
print(any([1, 2, []])) #返回 True
bin
bin 函数将十进制转换为二进制
应用实例:
print(bin(5)) #返回 101
oct
oct 函数将十进制转换为八进制
应用实例:
print(oct(5)) #返回 5
hex
hex 函数将十进制转换为十六进制
应用实例:
print(bin(5)) #返回 5
bool
any 函数将参数做bool运算。
空、None、0的布尔值为False, 其余都为True
应用实例:
print(bool(0)) #返回 False
print(bool(None])) #返回 False
print(bool(False)) #返回 False
print(bool(1)) #返回 True
bytes
bytes 函数查看字符串编码
应用实例:
test = "你好"
print(bytes(test, encoding='utf-8')) #返回'你好'的字符编码
print(bytes(test, encoding='utf-8').decode('utf-8')) #对test进行解码
#print(bytes(test, encoding='ascii')) #ascii不能编码中文
chr
bytes 函数查看字符串编码
应用实例:
print(chr(97)) #返回97所以应的ascii
print(chr(45)) #返回45所以应的ascii
dir
dir 函数查看某个对象下都有哪些方法
应用实例:
print(dir(all)) #返回97所以应的ascii
print(dir(str)) #返回45所以应的ascii
help
help 函数查看某个方法的用法
应用实例:
print(dir(all)) #返回97所以应的ascii
print(dir(str)) #返回45所以应的ascii
divmod
dir 函数做除法和求余数
应用实例:
print(divmod(10, 3)) #输出结果(3, 1),3位商、1为余数
eval
eval 将输入数据类型以字符串形式进行返回
输入参数:字符串
函数作用:将输入的字符串转换为表达式进行运算,并将运算结果进行输出返回。
应用实例:
#用法1 准换位字符串
#---------------------------------
list1 = [1, 5, 45, 'jkfdf']
print(eval("10/3")) #输出结果3.333333333
#用法2 将字符串中的表达式进行运算
#---------------------------------
calc = '45+45*2-(15-2)'
print(eval(calc)) #输出结果为122
hash
hash 可hash的数据类型即不可变数据类型,不可hash的数据类型即可变数据类型。
hash值的作用
应用实例:
print(hash('sfdkjfkghn')) #输出结果为一个10位10进制整数,每次运行可得到不同的哈希值
zip
zip 又称为拉链。zip函数有两个参数,将一个参数与第二参数的对应元素进行组合。
应用实例:
print(list(zip([1, 5, 6], ['fd', 'fd', 'fd']))) #输出:[(1, 'fd'), (5, 'fd'), (6, 'fd')]
max
max 求最大值
- max函数处理的是可迭代对象,相当于一个for循环取出每个元素进行比较,注意,不同数据类型之间不能进行比较
- 每个元素之间进行比较,是从每个元素的第一个位置一次比较,如果这一个位置分出大小,后面的都不需要比较了,直接得出这俩元素的大小。
应用实例:
list1 = [1, 5, 6, 3, 9]
print(max(list1)) #求列表中最大值
dict1 = {'key1':45, 'key2':21, 'key3':95, 'key4':12, }
print(mas(zip(dict1.values, dict1.keys))) #求字典中的最大值,并输出字典的键值和键名
min
min 求最小值
不同数据类型不能进行比较
应用实例:
list1 = [1, 5, 6, 3, 9]
print(min(list1)) #求列表中最小值
dict1 = {'key1':45, 'key2':21, 'key3':95, 'key4':12, }
print(min(zip(dict1.values, dict1.keys))) #求字典中的最小值,并输出字典的键值和键名
文件
打开文件
open()
文件的打开或创建可以使用内联模块的函数open()。该函数可以执行处理模式,设置打开文件的模式和状态。open()的声明如下所示:
def open(file_name, mode, buffering=-1, encoding="UTF-8", errors=None, newline=None, closef=True, opener=None)
参数file_name是被打开的文件名或文件绝对路径+文件名。如果file_name不存在,open函数会根据mode选项参数是否进行创建文件。
参数mode是指文件的打开方式。
参数buggering设置缓存模式。0表示不缓存;1表示行缓存;如果大于1则表示缓存区的大小,以字节为单位。
参数encoding表示文件读取或写入的编码格式。
参数errors为设置报错级别。
参数closefd为传入的file参数类型
open()函数返回一个open对象,open对象可以对文件进行各种操作。
文件的打开方式
参数 | 说明 |
---|---|
r | 以只读方式打开文件 |
r+ | 以读写的方式打开文件 |
w | 以写入的方式打开文件。若果文件存在则清空,再重新写入新的内容。如果文件不存在,则创建一个新文件 |
w+ | 以读写的方式打开文件。先删除源文件所有内容,在重新写入新的内容。如果文件不存在,则创建一个新文件 |
a | 以写入的方式打开文件,在文件的末尾追加新的内容。如果文件不存在,则创建一个新的文件 |
a+ | 以读写的方式打开文件,在文件的末尾追加新的内容。如果文件不存在,则创创建一个新的文件。 |
b | 以二进制模式打开文件。可以与r、w、a、+结合使用 |
U | 支持所有的换行符号。"\r"、"\n"、"\r\n"都表示换行 |
**注意:**对于图片、音频等文件必须使用 “b” 的模式读写。
open类用于文件管理,可以对文件进行创建、打开、读写、关闭等操作。file类的常用属性和方法如下表所示:
属性和方法 | 说明 |
---|---|
closed | 判断文件是否关闭。如果文件被关闭,返回True |
encoding | 显示文件的编码类型,默认为UTF-8 |
mode | 显示文件的打开模式 |
name | 显示文件的名称 |
flush() | 把缓冲区的内容写入磁盘 |
close() | 关闭文件 |
read(size) | 从文件中读取size个字节的内容作为字符串返回 |
readline(size) | 从文件中读取1作为字符串。如果指定size,表示每行每次读取的字节数,依然要读完整行的内容 |
readlines(size) | 把文件中的每一行存储在列表中返回。如果指定size,表示每次读取的字节数 |
seek(offset, whence) | 把文件的指针移动到一个新的位置。offset表示相对于whence的位置。whence用于设置相对位置的起点,0表示从文件开头计算;1表示从当前位置开始计算;2表示从文件尾开始计算。如果whence省略,offset表示行对文件头的位置 |
tell() | 返回文件指针的当前位置 |
next() | 返回下一行的内容,并将文件的执政移动到下一行 |
truncate(size) | 删除size个字节的内容 |
write(str) | 把字符串str的内容写入文件 |
writelines(sequence_of_strings) | 把字符串写入文件 |
文件的处理一般分一下3个步骤:
- 创建并打开文件,使用open()函数返回一个open对象。
- 调用open对象的read()、write()等方法处理文件。
- 调用close()方法关闭文件,释放open对象占用的资源。
**注意:**close方法是必须的。虽然Python提供了垃圾回收机制清理不再使用的对象,但是手动释放不需要的资源是一种良好的习惯。同时也显示地告诉Python的垃圾回收器,该对象需要被清除。
文件默认打卡的方式只读
#!/usr/bin/python3
context = '''hello world
Hello China
'''
#f = open("hello.txt", 'w') #以写的方式打开并创建文件
f = open("hello.txt", 'r') #打开文件
print(f.closed) #查询文件是否关闭
print(f.encoding) #查询文件打开的编码格式
print(f.mode) #查询文件打开的模式
print(f.name) #查询文件名
#f.write(context) #把字符串写入文件
print(f.readline()) #读取文件一行
print(f.readlines())
f.seek(0) #将文件指针指向文件头
print(f.readline())
f.close() #关闭文件
#方法1:默认打开方式 只读
#---------------------------------------------
fd = open("test_file.txt", encoding='utf-8') #打开文件名为test_file.txt文件,打开编码格式为utf-8
#方法2:以只读方式打开
#---------------------------------------------
fd = open("test_file.txt", 'r', encoding='utf-8') #以只写的模式打开
#方法3:以只写方式打开
#---------------------------------------------
fd = open("test_file.txt", 'w', encoding='utf-8') #以只写的模式打开
with as
打开文件后自动关闭文件
with open('a.txt', 'w') as fd: #创建文件
fd.wirte('hello\n') #写文件
关闭文件
close()
关闭以打开的文件
fd = open("test_file.txt", encoding='utf-8') #打开文件名为test_file.txt文件,打开编码格式为utf-8
fd.close() #关闭文件
写文件
write()
write 读文件内容
w:模式。文件不存在创建文件,若文件存在则清空文件文件。
返回值:返回写入数据的字节数。
fd = open("test_file.txt", 'w', encoding='utf-8') #打开文件名为test_file.txt文件,打开编码格式为utf-8
fd.write("helx") //向文件中写入内容不加换行
fd.write("helx\n") //向文件中写入内容加换行
fd.close() #关闭文件
writeable()
writeable 读文件内容
w:模式。文件不存在创建文件,若文件存在则清空文件文件。
#以只写方式打开
#-----------------------------------------------
fd = open("test_file.txt", 'w', encoding='utf-8') #打开文件名为test_file.txt文件,打开编码格式为utf-8
print(fd.writeable()) //输出True
fd.close() #关闭文件
#以只读方式打开
#-----------------------------------------------
fd = open("test_file.txt", encoding='utf-8') #打开文件名为test_file.txt文件,打开编码格式为utf-8
print(fd.writeable()) //输出False
fd.close() #关闭文件
writelines()
writelines 写文件
以整行的方式向文件写数据
#以只写方式打开
#-----------------------------------------------
fd = open("test_file.txt", 'w', encoding='utf-8') #打开文件名为test_file.txt文件,打开编码格式为utf-8
fd.writelines("fdagagga") //向文件中写入一行数据
fd.close() #关闭文件
+ 模式
r+:文件可读可写,写入文件的时候以追加的方式。写的时候以光标的位置开始写。
w+:
x+:
a+:
追加
a模式:本省就是写模式。若文件存在则则在文件的后面进行追加。
#以只写方式打开
#-----------------------------------------------
fd = open("test_file.txt", 'a', encoding='utf-8') #打开文件名为test_file.txt文件,打开编码格式为utf-8
fd.writelines("fdagagga") //向文件后添加数据
fd.close() #关闭文件
读文件
read()
读文件
fd = open("test_file.txt", encoding='utf-8') #打开文件名为test_file.txt文件,打开编码格式为utf-8
fd.close() #关闭文件
readable()
判断文件是否以可读方式打开
#以只读的方式打开
#-----------------------------------------------------
fd = open("test_file.txt", encoding='utf-8') #以默认只读方式打开
print(fdreadable()) #输出True
fd.close() #关闭文件
#以只写的方式打开
#-----------------------------------------------------
fd = open("test_file.txt", 'w', encoding='utf-8') #以只写方式打开
print(fdreadable()) #输出False
fd.close() #关闭文件
readlines()
从文件中一行一行的读
fd = open("test_file.txt", encoding='utf-8') #打开文件名为test_file.txt文件,打开编码格式为utf-8
print(fd.readlines()) #输出从文件中读取一行的内容
fd.close() #关闭文件
辅助操作
flush()
函数原型:def flush(self)
参数:无
功能:将内存的数据写入硬盘
返回值:None
应用示例:
#将内存中的数据写入硬盘
#--------------------------------------------------
fd = open('a.txt', 'w', 'utf-8') #创建文件
fd.write("hello") #写文件
fd.flush() #将内存中的数据写入硬盘
fd.close()
tell()
函数原型:def tell(self)
参数:无
功能:查询文件打开文件所在光标位置,一字节为单位
返回值:返回光标位置。
注意:read(3)代表读取3个字符,其余额文件内光标移动都是以字节为单位如seek、tell、read、truncate。
应用示例:
#查询文件光标位置
#--------------------------------------------------
fd = open('a.txt', 'w', 'utf-8') #创建文件
print(fd.tell()) #输出0
fd.write("hello") #写文件
print(fd.tell()) #输出5
fd.close()
seek()
函数原型:def seek(self, offset ,whence=io.SEEK_SET)
参数:
offset:默认从位置移动光标的位置。
whence:0、1、2;0:文件起始位置;1:当前位置;2:文件尾
功能:查询文件打开文件所在光标位置,一字节为单位
返回值:返回光标位置。
应用示例:
#查询文件光标位置
fd = open('a.txt', 'rw', 'utf-8') #创建文件
#使用写文件改变光标位置
#--------------------------------------------------
print(fd.tell()) #输出0
fd.write("hello") #写文件
print(fd.tell()) #查看当前光标位置
#使用seek将光标位置设置到起始位置
#--------------------------------------------------
fd.seek(0, 1) #设置光标位置为起始位置
print(fd.tell()) #查看当前光标位置
#使用seek将光标位置设置到末尾
#--------------------------------------------------
fd.seek(0, 2) #设置光标位置为末尾
print(fd.tell()) #查看当前光标位置
fd.close()
truncate()
函数原型:def truncate(self, size)
参数:
size:
功能:截取文件
返回值:返回光标位置。
文件的删除
文件的删除需要使用os模块和os.path模块。os模块提供了对系统环境、文件、目录等操作系统级的接口函数。如下表列出了os模块常用的文件处理函数:
os模块常用的文件处理函数
函数 | 说明 |
---|---|
access(path, mode) | 按照mode指定的文件权限访问文件 |
chmod(path, mode) | 改变文件的访问权限。mode用UNIX系统中的权限代号表示 |
open(filename, flag, mode=0777) | 按照mode指定的权限打开文件。默认情况下,给所有用户读、写、执行的权限 |
remoce(path) | 删除path指定的文件 |
rename(old, new) | 重命名文件或目录。old表示原文件或目录,new表示新文件或目录 |
stat(path) | 返回path指定文件的所有属性 |
fstat(path) | 返回大文件文件的所有属性 |
lseek(fd, pos, how) | 设置文件的当前位置,返回当前位置的字节数 |
startfile(filepath,operation) | 启动关联程序打开文件。例如,打开的是1个html文件,将启动IE浏览器 |
tmpfile() | 创建1个临时文件,文件创建在操作系统的临时目录中 |
注意: os模块的open()函数与内建的open()函数的用法并不相同
文件的删除与调用remove()函数实现。例如,首先创建1个文件hello.txt,然后判断文件是否存在或被打开,如果文件存在且已关闭则删除文件hello.txt。判断文件是否存在需要使用os.path模块,os.path模块用户处理文件和目录的路径。如下表所示os.path模块常用的函数。
os.path模块常用的函数
函数 | 说明 |
---|---|
abspath(path) | 返回path所在的绝对路径 |
dirname§ | 返回目录的路径 |
exists(path) | 判断文件是否存在 |
getatime(filename) | 返回文件的最后访问时间 |
getctime(filename) | 返回文件的创建时间 |
getmtime(filename) | 返回文件最后修改的时间 |
getsize(filename) | 返回文件的大小 |
isabs(s) | 测试路径是否为绝对路径 |
isdir(path) | 判断path指定的是否为目录 |
isfile(path) | 判断path指定的是否为文件 |
split§ | 对路径进行分割,并以列表的方式返回 |
splitext§ | 从路径中分割文件的扩展名 |
Splitdrive§ | 从路径中割驱动器的名称 |
walk(top, func, arg) | 边路目录数,与os.walk()的功能相同 |
#删除文件演示示例:
import os
file("hello.txt", "w")
if os.path.exists("hello.txt"):
os.remove("hello.txt")
目录的基本操作
目录是文件存储的集合,对于目录的操作涉及目录的创建、删除和目录的遍历等内容。
目录的创建删除
os模块提供了针对目录进行操作的函数。如下表列出了os模块中常用的目录处理函数。
os模块常用的目录处理函数
函数 | 说明 |
---|---|
mkdir(path, mode=0777 | 创建path指定的1个目录 |
makedirs(name, mode=0511) | 创建多级目录,name表示为"path1/path2"… |
rmdir(path) | 删除path指定的目录 |
removedirs(path) | 删除path指定的多级目录 |
listdir(path) | 返回path指定目录下的所有文件名 |
getcwd() | 返回当前工作目录 |
chdir(path) | 将当前目录改变为path指定的目录 |
walk(top, topdown=True, οnerrοr=Noen | 遍历目录树 |
import os
os.mkdir("hello") #创建一个名为 "hello" 的目录
os.rmdir("hello") #删除一个名为 "hello" 的目录
os.makedirs("hello/world") #创建多级目录,先创建 "hello" 目录,然后在 "hello" 目录下创建 "world" 目录
os.removedirs("hello/world") #删除目录 "hello" 和 "world" 目录
**注意:**函数makedirs()一次可创建多个目录。函数removedirs()一次可删除多个目录。函数mkdir()一次只能创建一个目录。函数rmdir()一次只能删除一个目录。
总结:
python默认打开文件的方式时 ‘rt’,对于二进制文件可以跨平台,所有操作系统的数据的存放形式都是以二进制的形式存放数据。
循环文件的推荐方式:
#方法1:输出文件
#---------------------------------------------
fd = open("test_file.txt", encoding='utf-8') #打开文件名为test_file.txt文件,打开编码格式为utf-8
for i in fd:
print(i)
迭代
什么是迭代器协议:
- 迭代器协议是指:对象必须提供一个 __ next __()* 方法,执行该方法要么返回迭代中的下一项,要么就引起一个Stoplteration异常,以终止迭代(只能往后走不能往前退)
- 迭代器对象:实现了迭代器协议的对象(如何实现:对象内部定义一个 iter() 方法)
- 协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum、min、max函数等)使用了迭代器协议访问对象。
对于字符串、列表、元组可以通过下标的方式进行访问还可以通过下标的方式进行遍历,但是字典、集合这种数据类型是无序的然而并没有什么下标,当你想遍历字典、集合这种数据类型时那你又该如何操作呢?这时一个让人头大的问题,其实for循环就是一个基于迭代器协议的对象,可以通过for循环进行对数据类型的所有对象进行遍历,其实for循环在循环之前是先调用–iter–()方法,将其数据类型转换为迭代对象,然后使用迭代器协议进行对迭代器对象的方访问方法。
for循环的原理:
ls1 = [1, 2, 3, 5]
for i in str1:
print(i)
#创建可迭代对象
#---------------------------------------------
iter_test = str1.__iter__() #将str1转换为可迭代对象然后返给iter_test,那么iter_test就是一个可迭代对象
'''
可迭代对象可是使用 __next__() 方法
'''
for i in range(len(str1)):
print(iter_test.__next__())
生成器
生成器理解为一种数据类型,这种数据类型实现了迭代器协议,所以生成器是可迭代对象。
python中提供了两种不同的生成器:
- 生成器函数:常规函数的定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行;
- 生成器表达式:类似列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表。
三元表达式
其中三元表达式又成为三目运算,三元的意思就是说在此表达式中含有三个运算符。
python中三元运算符的使用方法:if和else之间为一个bool值,如果bool值为真则返回if前面的值,如果bool值为家则返回else后面的值。
三元表达式应用实例:
#三元表达式的使用
#---------------------------------------------
#str1 = 'hello'
str1 = 'world'
res = 'yes' if str1 == 'hello' else 'no'
print(res) #结果输出 no
列表解析
列表即系可以很方便的生成一个列表,但是类表确实是生成了一个列表,当类表很大时,所占内存就比较大了。
#列表解析
#---------------------------------------------
list1 = ['str%d'%i for i in range(10)] #两元
for i in list1:
print(i)
#列表解析
#---------------------------------------------
list1 = ['str%d'%i for i in range(10) if i<5] #三元表达式
for i in list1:
print(i)
生成器表达式
生成器创建的就是可迭代对象,生成器有两种方式可以实现:
- 生成器表达式;
- 生成器函数,使用yield。
#生成器
#---------------------------------------------
iter_test = ('str%d' %i for i in range(10)) #使用生成器表达式创建可迭代对象
print(iter_test.__next__())
print(next(iter_test))
#使用yield创建生成器表达式
#---------------------------------------------
def res_iter(): #创建生成器函数
yield 12, 'fd', 'f2', 890
yield 'fd'
yield 89
yield 90
iter_test = res_iter()
print(iter_test.__next__()) #输出迭代对象
print(next(iter_test)) #输出迭代对象
print(next(iter_test)) #输出迭代对象
print(next(iter_test)) #输出迭代对象
print(next(iter_test)) #报错,可迭代对象已经全部输出
send()方法
函数原型:def send(self, value)
生成器有一个send方法
作用:一部分作用于next()方法一样,但是在send()方法可以行生成器发送参数。
返回值:返回yield的结果
应用示例
def test():
print("开始啦")
firt = yield 1
print("第一次", firt)
firt = yield 2
print("第二次", firt)
print("结束")
t = test()
res = t.__next__()
print(res)
res = t.send(12)
print(res)
res = t.send(13)
print(res)
总结:
- 把列表解析的[]换成()得到的就是生成器表达式;
- 列表解析与生成器表达式是一种便利的编程方式,只不过生成器更节省内存;
- python不但使用可迭代协议,让for循环变得更加通用。大部分函数,也是使用迭代器协议访问对象。例如,sum函数是python的内置函数,该函数使用迭代协议访问对象,而而生成器实现了迭代协议,所以,我们可以直接使用这样的一些列的可迭代函数。
- 生成器函数使用yield进行返回,可以保留函数的返回状态,每遇到yield就返回。
- 语法上和函数类似:生成器函数与常规函数几乎一样。他们都是使用def语句进行定义,区别在于,生成器使用yeild语句返回一个值,并且函数可以在下次被调用时继续向下执行,而常规函数使用return函数返回一个值,常规函数遇到return时直接结束函数,在下次调用此函数时则又是从新开始。
优点:
- 生成器的好处是延迟计算,调用一次返回一个结果。也就是说,他不会一次生成多个结果,这对于大数据数理,将会非常有用;
- 生成器还能有效提高代码的可读性。
模块
模块的创建
创建模块myModule
module_name:模块名称\被调用文件名
func:被调用模块 内部函数\类\变量
Creat file name call_myModule.py
def func():
print("MyModule.func()")
class MyClass:
def myFunc(self):
print("MyModule.Myclass.myFunc()")
在call_myModule.py文件中使用import调用模块myModule
# Creat file name myModule.py
import myModule #调用myModule模块
myModule.func()
myClass = myModule.MyClass()
myClass.myFunc()
模块的调用
导入外部函数方法有:
improt module_name #导入模块名,使用内部函数/类事需要加module_name.
from module_name import func #导入模块内部函数func
from module_name import * #导入模块内部所有函数/类
在使用import调用外部模块的时候,当执行到外部函数的之后,程序将转向被调用函数所在为文件内并且执行该文件,当执行完改文件之后转向被调用函数,被调用函数执行完之后才返回主文件继续执行。
使用import调用的时候,想用module_name文件内部函数,则必须使用module_name.func的形式调用module_name文件内部函数。而from module_name import func引用模块的方式是在使用func函数的时候不需要添加module_name.前缀。
模块属性
在使用import导入模块的时候,那么模块被导入时模块内部的可执行程序将会被执行。如果在导入模块时内部程序不被执行,可以使用模块内部属性(__name __ )进行判断当前模块是否是程序的入口。
Creat file name call_myModule.py
def func():
print("MyModule.func()")
class MyClass:
def myFunc(self):
print("MyModule.Myclass.myFunc()")
if __name__ == "__main__":
print("myModule作为主程序运行")
else:
print("myModule被另一个模块调用")
内置模块
json模块
对于json模块内部总共两个函数,分别是dumps()和loads()。
dumps()函数的作用就是把用户输入的数据转换为类型符+数据字符串, 转换为dump字符串。
lis1 = ['012', 123, 456] #定义列表
dic1 = {"name1":'hello', 'name2':'world'} #定义字典
tup1 = ('fd', 2, 'hehe') #定义元组
gat1 = {1, 2, 3, 4} #定义集合
data1 = json.dumps(lis1) #将列表转换为字符
data2 = json.dumps(dic1) #将字典转换为字符
data3 = json.dumps(tup1) #将元组转换为字符
#data4 = json.dumps(gat1) # 经验证json模块不能处理集合类型
print(data1) # ["012", 123, 456]
print(data2) # {"name1":"hello", "name2":"world"}
print(data3) # ("fd", 2, "hehe")
#print(data4) #
lis2 = json.loads(data1) #将json处理过的字符串又转换为原来的数据类型
dic2 = json.loads(data2) #
tup2 = json.loads(data3) #
print(lis2)
print(dic2)
print(tup2)
xml模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但是json使用起来更加简单,不过在很早以前json还没有诞生是,xml已经应用比较防范了,至今很多传统的公司如金融行业很多系统的接口还是主要是xml。
xml的的格式如下,就是通过o节点来区分数据结构的。
re模块
对象
面型对象的程序设计提供了一种新的思维方式,软件涉及的焦点不再是程序的逻辑流程,而是软件或程序中的对象以及UI想之间的关系。使用面向对象的思维进行程序设计,能够更好地设计软件架构、维护软件模块、易于框架和组件的重用。
面向对象编程概述
面向对象是一种方法学。面向对象是一宗描述业务问题——设计业务实体和实体之间的关系的方法。面向对西向技术已经成为当今软件设计和开发领域的主流技术。面向对象主要用于软件开发的分析和设计阶段,通常使用UML(统一建模语言)进行建模。 同意
统一建模语言并不是软件设计开发的方法,而是一种描述软件开发过程图形化标记。MUL使用若干模型图来描述软件开发中的每个重要步骤。
- 用例图
用例图描述系统使用者于系统之间的交互关系,用例图通常用语系统的分析j阶段,分析系统中主要的流程。类图用于描述不同的业务实体以及实体之间的关系。 - 活动图
活动图使用例图的补充,用于分析复杂的用例,表示用例中的逻辑行为。活动图类似于传统的数据流程图,可以描述业务的流程、帮助分析人员确定例中的交互和用例之间的交互关系。 - 状态图
状态图用于对系统的行为进行建模,用于分析和设计阶段的之间的过渡时期。状态图和活动图有些类似,状态图是对当个对象的描述,强调对象内部状态的变迁过程。 - 类图
类图包括属性、操作以及访问权限等内容。类图用于系统设计阶段,根据系统用例提炼出系统中的对象。类图是面向对象设计的核心,通过类图可以表示抽象、继承、多态等面向对象特性。能过表现系统的架构设计,系统中对象之间的层次关系。 - 序列图和协助图
序列图和协助图都可以用于描述系统中对象之间的行为,是对系统具体行为的设计。序列图和协助图通常用语类图设计完成后的一个步骤。序列图是对用例图的具体实现,通过消息的方式描述系统中对象的生命周期和控制流程。而协助图突出对消息的建模,描述系统对象之间的交互关系。 - 组件图和部署图
组件图用于描述系统组件之间的交互以及类和组件之间的依赖关系。部署图用于描述系统的部署以及组件之间的配置。
这些图像标记偶可以使用UML建模工具绘制,例如visio和Rational Rose。使用这些建模工具可以准确、快速的描述系统的行为。visio是office系列的工具之一,使用简单、容易上手。而Rational Rose能更好的管理对象,能通过模型生成各种语言的代码,以及对代码更新来同步模型等特性。使用Rational Rose能更好的管理对象,但是Rational Rose软件庞大,必须学习每种图像的绘制方法。建模工具只是辅助系统分析、设计的手段,系统分析人员甚至可以使用手写的方法来描述系统的墨香。重要的能够清晰、准确的分析和设计,而不是软件工具的优劣。
类和对象
在面型对象的设计中,程序员可以创建任何新的类型,这些类型可以描述每个对象包含的数据类型,这猴子那个类型称之为类。类是一些对象的抽象,隐藏了对象内部复杂的结构和实现。类由变量和函数两部分构成,类中的变量称之诶成员变量,类中的函数称之为成员函数。
类和对象象的区别
类和对象是面向对象中的两个重要概念,对于初学经常把类和对象混为一谈。类是客观世界中失误的抽象,而对象类实例化的变量。例如定义一个的数据变量,int number = 32;int就是数据的类型,而number就int的一个对象。int类的属性有必须是整数、整数的范围为32位等等,但number是int类实例化的一个对象,number就具备int类的所有属性。
类的定义
Python使用class保留定义一个类,类名的首字母一般要大写。当程序员需要创建的类型不能用简单的类型来表示时,就需要定义类,然后利用定义的类创建对象。类把需要使用的变量和函数组合在一起,这种方式称之为封装。类兴义的就够如下所示:
class Class_name:
...
类必须用保留字class定义,保留字class后面的是类名。类的主题有一些列的属性和方法组成。下面这段代码创建一个简单地水果类,水果类具有成长的行为,因此定义1个方法grow():
#类的创建
class Fruit:
def grow(self):
print("Fruit grow ...")
第2行代码定义一个名为“Fruit”的类。第3行代码,在Fruit中创建了1个方法grow()。累的方法至少有1个参数self,self参数的含义会在后面中介绍。
主要:类的方法必须有1个self参数。但是方法被调用时,可以不传递这个参数。
对象的创建
创建对象的过程称之为实例化,当一个对象呗创建后,包含三个方面额特向:对象的句柄、属性和方法。对象的句柄用于区分不同的对象,当对象被创建后,对象会获取一块内存空间,存储空间的地址为对象的标志。对象的属性和方法与类的成员变量和成员函数相对应:
if __name__ == "__main__":
fruit = Fruit()
fruit.grow()
第2行代码对Fruit类进行实例化,Python的实例化与Java不同,并需要new保留字。Python的实例化与函数调用相识,使用类名加货号的方式。
第3行代码调用Fruit类的grow()方法。
输出结果:Fruit grow …。类的方法中至少有一个参数self。
Python对象的体系结构
1. 经典对象
经典对象的内部有属性和方法组成。属性可以是数据类型,可以可以是函数类型。如果属性是函数类型,则该属性就是1个方法。Python的方法很特别,解释器把类的方法也看做属性。类的内部提供了一些内部的方法,方法名是有前后两个下划线加字母组成。例如构造函数__init__。字符串“init”前都有两个下划线。
2.新型对象
新型对象内建object对象,该对象hi内建类型和新型对象的父类,或称为基类。object也可以看作是对象。如果要定义新型对象,必须继承object对象。语法格式如下所示:
class_name(object):
...
新型对象提供了对类和静态方法的支持。类方法可以被类和类的实例化对象调用。classmethod()可以把方法定义为类方法。静态方法可以被类直接调用,可以被所有的实例化对象共享。staticmethod()可以把方法定义为静态方法。
属性和方法
类由属性和方法组成。类的属性是对数据的封装,而类的方法则表示对象具有的行为。Python的构造函数、析构函数、私有属性或方法多是通过名称约定区分的。此外,Python还提供了一些有用的内置方法,简化类的实现。
类的属性
类的属性分为私有属性和公有属性。C#、Java语言的私有属性或方法使用private保留字定义,不同的Python并没有提供公有和私有权限的修饰符。类的私有属性不能被该类之外的函数调用,类属性的作用范围完全取决于属性的名称。如果函数、方法或属性额名字以两个下划线开始,则表示私有类型;没有使用两个下划线开始则表示公有属性。类的方法同样遵守这个约定,Python中有许多语法是通过约定变量名称的方式实现的。
注意: Python没有保护类型的修饰符。
Python的属性分为实例化属性和静态属性。实例化属性以self作为前缀的属性。__init__方法即Python类的构造函数,如果__init__方法中定义的变量没有使用self作为前缀声明,则该变量只是普通的局部变量。类中其他方法定义的变量只是局部变量,而非类的实例属性。
C#、Java中有一类特殊的属性称为静态变量。静态变量可以被类直接调用,而不是被实例化对象调用。当创建新的实例化对象后,静态变量并不会获得新的内存空间,而是使用类创建静态变量的内存空间。因此,静态变量能够被多个实例化对象共享。在Python中静态变量称之为静态属性。
class Fruit:
price = 0 #类属性 属于静态属性 所有实例化属性共用 类属性即可以被类访问也可以被对象访问
def __init__(self):
self.color = "red" #实例属性 可以被实例化对象调用而可是被实例对象的私有属性
zone = "China" #局部变量 局部对象不能对被对象调用
if __name__ == "__main__":
print(Fruit.price)
apple = Fruit()
print(apple.color)
Fruit.price = Fruit.price + 10
print("apple's price:" + str(apple.price))
banana = Fruit()
print("banana's price:" + str(apple.price))
类的私有属性的定义方式:使用双下划加属性名称(__color)。
Python提供了直接访问私有属性的方式,可用于程序的调试和调试。私有属性访问的格式如下所示:
instance._classname__attribute
#instance表示实例化对象;classname表示类名称;attribute表示私有属性。
class Fruit:
def __init__(self):
self.__color = "red"
class Apple(Fruit):
pass
if __name__ == "__main__":
fruit = Fruit()
apple = Apple()
print(Apple.__bases__) #输出基类组成的元组
print(apple.__dict__) #输出属性组成字典
print(apple.__module__) #输出类所在的模块名
print(apple.__doc__) #输出doc文档
类的方法
类的方法也分为公有方法和私有方法。私有函数不能被该类之外的函数调用,私有的方法也不能被外部的类或函数调用。C#、Java中静态方法使用保留字static声明,而Python使用函数staticmethod()或“@ staticmethod”指令的方式把普通的函数转换为静态方法。Python的静态方法并没有和类的实例进行名称绑定,Python的静态方法相当于全局函数。
演示类的方法和静态方法的使用
class Fruit:
price = 0
def __init__(self):
self.__color = "red"
def getColor(self): #定义公有方法getColor()
print(self.__color)
@ staticmethod #使用“@ staticmethod”指令声明getPrice为静态方法
def getPrice(): #静态方法
print(Fruit.price)
def __getPrice(): #定义了__getPrice()私有方法,该方法没有提供参数self
Fruit.price = Fruit.price + 10
print(Fruit.price)
count = staticmethod(__getPrice) #静态方法 调用staticmethod()把__getPrice()转换为静态方法,并赋值给count。count()即为Fruit类的静态方法。
if __name__ == "__main__":
apple = Fruit()
apple.getColor()
Fruit.count()
banana= Fruit()
Fruit.count()
Fruit.getPrice()
Python中还有一种方法称之为类方法。类方法的作用于静态方法相似,都可以被其他实例对象共享。不同的类方法必须提供self参数。类方法可以使用函数classmethod()或“classmethoc()”指令定义。
演示程序的静态方法修改为类方法。
@ classmethod
def getPrice(self): #类方法
print(self.price)
def __getPrice(self):
self.price = self.price + 10
print(self.price)
count = classmethod(__getPrice) #类方法
类方法的使用和静态方法十分相似。如果某个方法需要被其它实例共享,同时又需要使用当前实例的属性,则将其定义为类方法。
内部类的使用
Java可以在类的内部定义类,Python同样存在这种语法。这种在某个类内部定义的类称之为内部类。内部类中的方法可以使用两种方法调用。
第一种方法是直接使用外部l类调用内部类,生成内部类实例,再调用内部类的方法。调用格式入校:
object_name = outclass_name.inclass_name()
object_name.method()
#其中,outclass_name表示外部类的名称,inclass_name()表示内部类的名称,object_name表示内部类的实例。
第二种方法是向对外部类进行实例化,然后再实例化内部类,最后调用内部类的方法。调用格式如下:
out_name = outclass_name()
in_name = out_name.inclass_name()
in_name.method()
其中,out_name()表示外部类的实例,in_name表示内部类的实例
演示内部类的使用方法
class Car:
class Door: #内部类
def open(self): #定义了Door类的方法open()
print("open door")
class Wheel: #内部类
def run(self): #定义了Wheel类的方法run()
print("car run")
if __name__ == "__main__":
car = Car()
backDoor = Car.Door() #内部类的实例化方法一
frontDoor = car.Door() #内部类的实例化方法二
backDoor.open()
frontDoor.open()
wheel = Car.Wheel()
wheel.run()
注意:内部类不适合描述类之间组合关系,而应把Door、Wheel类的对象作为类的属性使用。内部类容易造成程序结构的复杂,不提倡使用。
__init__方法
**构造函数用于初始化类的内部装填,为类的属性设置默认值。**C#、Java的狗战术是与类同名的方法,而Python的构造函数名为__init__。__init__方法除了用于定义实例变量外,还用于程序的初始化。__init__方法是可选的,如果不提供__init__方法,Python将会给出1个磨人的__init__方法。
对使用Fruit类进行创建并初始化fruit对象
class Fruit:
def __init__(self, color): #__init__是类Fruit的初始化函数,即构造函数,初始化私有属性 __color
self.__color = color
print(self.__color)
def getColr(self): #获取__color属性的值,对Fruit类的属性__color进行赋值,需要前缀self。否则Python解释器将任务·将认为__color是__init__()中的局部变量。
print(self.__color)
def setColor(self, color):
self.__color = color
print(self.__color)
if __name__ == "__main__":
color = "red"
fruit = Fruit(color) #带参数的构造函数 创建Fruit对象fruit,并fruit对象的属性进行初始化
fruit.getColr() #获取fruit对象的属性__color
fruit.setColor("blue") #设置fruit对象的属性__color
注意:1.Python可以随时调用__init__()函数,而C#、Java并不能直接调用构造函数;2.__init__方法和Java、C++等开发语言一样不能返回任何值。
__del__方法
析构函数用于释放对象占用的资源。 Python提供了析构函数__del__()。析构函数可以显式的释放对象占用的资源,是一种释放资源的方法。析构函数也是可选的。如果程序中不提供析构函数,Python会在后台提供默认的析构函数。
Python的析构函数__del__()的使用方法
class Fruit:
def __init__(self, color): #初始化属性__color
self.__color = color
print(self.__color)
def getColor(self):
print(self.__color)
def __del__(self): #析构函数 析构函数__del__ 参数self对于析构函数同样是不可缺少的。
self.__color = ""
print("free ...")
def grow(self):
print("grow ...")
if __name__ == "__main__":
color = "red"
fruit = Fruit(color) #带参数的构造函数
fruit.getColor()
fruit.grow() #隐式执行析构函数 程序执行结束会自动隐式调用对象的析构函数
#del fruit #显式执行析构函数
对于C++语言,析构函数是必须的 ,程序员要为对象分配内存空间,同时也要手动释放内存。使用Python编写的程序可以不考虑后台的内存管理,直接面对程序的逻辑即可。
垃圾回收机制
Java中没有提供析构函数,而是采用垃圾回收机制清理不再使用的对象。Python也采用垃圾回收机制清除对象,Python提供了gc模块释放不再使用的对象。垃圾回收机制有许多种算法,Python采用的是引用计数的方式。当某个对象在其作用于不再被其他对象引用时,Python就会自动清除该对象。垃圾回收机制很好地避免了内存泄漏的发生。函数collect()可以一次性手机所有带处理的对象。
使用gc模块显式的调用垃圾回收器
import gc
class Fruit: #初始化name、color
def __init__(self, name, color): # 初始化name、color属性
self.__name = name
self.__color = color
def getColor(self):
return self.__color
def setColor(self, color):
self.__color = color
def getName(self):
return self.__name
def setName(self, name):
self.__name = name
class FruitShop: #水果店类
def __init__(self):
self.fruits = [] #定义属性fruits,fruits是1个列表,用于存放水果店的水果
def addFruit(self, fruit): #定义方法addFruit(),把对象fruit添加到fruits列表中
fruit.parent = self #设置fruit对象的parent属性为self。即把FruitShop实例化对象的引用关联到fruit对象上
self.fruits.append(fruit)
if __name__ == "__main__":
shop = FruitShop()
shop.addFruit(Fruit("apple", "red")) #向shop对象中添加两个Fruit添加两个Fruit对象
shop.addFruit(Fruit("banana", "yellow"))
print(gc.get_referrers(shop)) #列出shop对象的所有对象
del shop #删除对象,但是shop对象关联的其他对象并没有释放
print(gc.collect()) #调用函数collect()释放shop对象关联的其他对象,collect()返回结果表示释放的对象个数。输出结果为7
注意:垃圾回收器在后台执行,对象被释放的时间是不能确定的。如果要设置调用垃圾回收器,可以使用gc模块的函数实现。
类的内置方法
Python类定义了一些专用的方法,这些专用方法可以用于不同的应用场合,丰富了程序设计的功能。前面提到的__init__()、del()就是类的内置方法。
常用的内置方法
内置方法 | 说明 |
---|---|
__init __(self, …) | 初始化对象,在创建新对象时调用 |
__del __(self) | 释放对象,在对象呗删除之前调用 |
__new __(cls, *args, **kwd) | 实例的生成操作 |
__str __(self) | 在使用print语句时被调用 |
__getitem __(self, key) | 获取序列的索引key对应的值,等价于seq[key] |
__len __(self) | 在调用内联函数len()时被调用 |
__cmp __(src, dst) | 比较两个对象src和dst |
__getattr __(s, name) | 获取属性的值 |
__setattr __(s, name) | 设置属性的值 |
__delattr __(s, name) | 删除name属性 |
__getattribute __() | __getattribute __()的功能与 __getattr __()类似 |
__It __(self, other) | 判断self对象是否大于other对象 |
__ge __(self, other) | 判断self对象是否小于other对象 |
__le __(self, other) | 判断self对象是否大于或等于other对象 |
__eq __(self, other) | 判断self对象是否小于或等于other对象 |
__call __(self, other) | 判断self对象是否等于other对象 |
__gt __(self, other) | 把实例对象作为函数调用 |
方法的动态特性
Python作为动态脚本语言,编写的程序具有很强的动态性。可以动态添加类的方法,把某个已经定义的函数添加到类中。添加新方法的语法格式如下所示:
class_name.method_name = function_time
#其中,class_name表示类名,method_name表示1个已经存在的函数,函数的内容即为新的方法的内容。
演示方法的动态添加。
#### 演示方法的动态添加
class Fruit: #定义Fruit类
pass
def add(self): #定义add方法
print("add grow ...")
def updata():
print("updata grow ...")
if __name__ == "__main__":
Fruit.grow = add #向Fruit类中添加add方法,并命名为grow
fruit = Fruit()
fruit.grow() #调用添加的方法
fruit.grow = updata #将fruit对象中的grow方法修改为U盘data方法
fruit.grow()
继承
继承是面向对象的重要特性之一。继承是相对两个类而言的父子关系,子类继承父类的所有公用实例变量和方法。继承实现了代码重用。Python不提倡过度的包装,所有封装性的Python程序中体现的比较弱,实际上继承欧多态已经足够好。
使用继承
当类设计完成以后,就可以考虑类之间的逻辑关系。类类之间存在继承、组合、依赖等关系,可以采用UML工具表示类之间的关系。例如,有两个子类Apple、Banana继承自父类Fruit,父类Fruit中有1个共有的实例变量和1个公有的方法。可以用类图来描述3个类之间的关系。
公有实例变量额方法有“ + ”表示。Apple、Banana可以继承Fruit类的实例变量color和方法grow()
继承可以重用已经存在的数据和那个味减少代码的重复编写。Python在类名后使用一对括号表示继承关系,括号中的类为父类。如果类定义了__init__方法,子类必须显示调用父类的__init__方法。如果子类需要扩展父类的行为,可以添加__init__方法的参数。
演示继承的实现
#### 演示继承的实现
class Fruit: #定义父类Fruit
def __init__(self, color): #在父类中定义__init__方法中定义类公有属性color
self.color = color
print("fruit's color:%s"%self.color)
def grow(self): #定义公有方法grow()
print("grow ...")
class Apple(Fruit): #定义Apple类,继承父类Fruit
def __init__(self, color):
Fruit.__init__(self, color)
print("apple's color:%s"% self.color)
class Banana(Fruit): #定义Banana类,继承父类Fruit
def __init__(self, color):
Fruit.__init__(self, color)
print("banana's color:%s"%self.color)
def grow(self): #子类中的定义grow方法,覆盖了父类Fruit中的grow()方法
print("banana grow ...")
if __name__ == "__main__":
apple = Apple("red")
apple.grow()
banana = Banana("yellow")
banana.grow()
在子类中还可以使用super类的super()调用父类的__init__方法。super()声明如下所示:
super(type, obj)
#type是某个类,obj是type类的实例化对象,super()可以绑定type类的父类。
使用super()调用父类的__init__方法:
#### 使用super()调用父类
class Fruit(object):
def __init__(self):
print("parent")
class Apple(Fruit):
def __init__(self):
super(Apple, self).__init__() #self对象是Apple类的实例
print("child")
if __name__ == "__main__":
Apple()
**注意:**super类的实现代码继承了object,因此Fruit类必须继承obj。如果不继承object,使用super()将出现错误。
抽象类的模拟
使用继承之后,子类可重用父类中的属性和方法,并且可以对继承的方法进行重写。
抽象类是一对失误的特征和行为的抽象,抽象类由抽象方法组成。Java中可以把Fruit类设计为抽象类,而Python只能用1个普通类来表示Fruit。抽象类的特征是能被实例化,只能通过Python的NotImplementedError类模拟抽象类。NotImplementedError类继承自Python运行时错误类RuntimeError。当对抽象类进行实例化时,将抛出该异常。
模拟抽象类的实现
def abstract(): #代码定义abstract(),该函数抛出NotImplementedError异常
raise NotImplementedError("abstract")
class Fruit:
def __init__(self):
if self.__class__ is Fruit: #如果实例化的类是Frui,则抛出异常
abstract()
print("Fruit")
class Apple(Fruit):
def __init__(self):
Fruit.__init__(self) #调用父类的__init__
print("Apple")
if __name__ == "__main__":
apple = Apple()
#fruit = Fruit() #抛出异常NotImplementedError:abstract
在Python3中将提供抽象类
多态性
动态多态是指发出同样的消息被不同的类型的对象接收时,有可能导致完全不同的行为。即,在用户不作任何干预的环境下,类的成员函数的行为能根据调用它的对象类型自动做出适应性调整,而且调整是发生在程序运行时。
多态示例
class Fruit:
def __init__(self, color = None):
self.color = color
class Apple(Fruit):
def __init__(self, color = "red"):
Fruit.__init__(self, color)
class Banana(Fruit):
def __init__(self, color = "yellow"):
Fruit.__init__(self, color)
class FruitShop:
def sellFruit(self, fruit):
if isinstance(fruit, Apple): #判断参数fruit的类型
print("sell apple")
if isinstance(fruit, Banana):
print("sell banana")
if isinstance(fruit, Fruit):
print("sell fruit")
if __name__ == "__main__":
shop = FruitShop()
apple = Apple("red")
banana = Banana("yellow")
shop.sellFruit(apple) #输出结果为sell apple、sell fruit
shop.sellFruit(banana) #输出结果为sell banana、sell fruit
多重继承
Python支持多重继承,即1个类可以继承多个父类。多重继承的语法格式如下所示:
class_name(parent_class1, parent_class2, ...)
class_name是类名,parent_class1和parent_class2是父类名。
多重继承示例
class Fruit(object):
def __init__(self):
print("initialize Fruit")
def grow(self):
print("initialize Vegetable")
class Vegetable(object):
def __init__(self):
print("initialize Vegetable")
def plant(self):
print("plant")
class Watermelon(Vegetable, Fruit): #多重继承
pass
if __name__ == "__main__":
w = Watermelon()
w.grow()
w.plant()
注意: 由于Watermelon继承了Vegetable、Fruit类,因此Watermelon将继承__init__()。但是Watermelon只会调用第1个被继承的类的__init__,即Vegetable类的__init__()。
更好的继承方式
运算符用于表达式的计算,但对自定义的对象似乎并不能进行计算。运算符的重载可以实现对象之间的运算。Python把运算符和类的内置方法关联起来。每个运算符都对应1个函数。
运算符的重载
运算符用于表达式的计算,但对于定义的对象似乎并不能进行计算。运算符的重载可以实现对象之间的运算。Python把运算符和类的内置方法关联起来,每个运算符都对应一个函数。
运算符的重载
class Fruit:
def __init__(self, price = 0):
self.price = price
def __add__(self, other): #重载加号运算符
return self.price + other.price
def __gt__(self, other): #重载大于运算符
if self.price > other.price:
return self.price
else:
return other.price
class Apple(Fruit):
pass
class Banana(Fruit):
pass
if __name__ == "__main__":
apple = Apple(3)
print("苹果的价格:", apple.price)
banana = Banana(2)
print("香蕉的价格:", banana.price)
print (apple > banana)
total = apple + banana
print("合计:", total)
Python与设计模式
设计模式简介
设计模式(Design Pattern)是面型对象程序设计的解决方案,是复用性程序设计的经验总结。设计模式的概念最早起源于建筑设计大师Christopher Alexander关于城市规划和建筑设计的著作《建筑的永恒方法》,尽管该著作是针对建筑领域,但是其思想也适用于软件开发领域。设计模式的目的是形成典型问题的解决方案,设计出可复用软件结构。设计模式是与语言无关的,任何语言都可以实现设计模式。
设计模式根据使用目的不同分为创建型模式(Creatioal Pattern)、结构型模型(Structural Pattern)和(行为模型(Behavioral Patterns)。
创建模型式提出了对象创建的解决方案以及数据封装的方法。降低了创建对象时代码实现的复杂度,使对象的创建满足特定的要求。例如,工厂模式、抽象工厂模式、但例模式、生成器模式等。
结构型模式描述对象之间的体系结构,通过组合、继承等方式改善体系结构,降低体系结构中组件的依赖性。例如,适配器模式、桥模式、组合模式、装饰器模式、外观模式等。
行为型模型秒速了对象之间的交互和各自的职责,有助于实现程序中对象的通讯和流程的控制。例如,迭代器模式、解释器模式、中介者模式、观察者模式等。
Python是一种简单、灵活的动态语言,Python简化了面型对象语言的复杂性,但却没有降低面向对象的特性。使用Python同样可以实现各种设计模式,而且是想过程比较简单。
异常处理与程序调用
Python标准库的每个模块都使用了异常,异常在Python个除了可以捕获错误,还有一些其他用途。当程序中出现异常或错误是,最后的解决办法就是调用程序。Python的IDE工具提供了不同的功能的程序调试。
异常处理
Python提供了强大的异常处理机制,程序员通过捕获异常可以提高程序的健壮性。异常处理还具有释放对象、中止循环的运行等作用。
Python中的异常
异常(Exception)是指程序中的例外、违规情况。异常机制是指当程序出现错误后,程序的处理方法,异常机制提供了程序正常退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器。如序列的序列的下标出界、打开不存在的文件、空引用异常等。当异常被引发时,如果没有代码处理该异常,异常将被Python接收处理。当异常发生时,Python解释器将输出一些相关的信息并中止程序的运行。
StandardErrorl类中常见的异常
异常名 | 说明 |
---|---|
ZeroDivisionError | 除数为0引发的异常 |
AssertionError | assert语句失败引发的异常 |
AttributeError | 属性引用、分配错误异常 |
IOError | I/O操作引发的异常,例如文件的读写 |
OSError | os模块的函数引发的异常 |
ImportError | 导入模块时引发的异常 |
IndexError | 索引操作者错误引发的异常 |
KeyError | 使用字典中不存在的key值而引发的异常 |
MemoryError | 内存耗尽而引发的异常 |
NameError | 变量名不存在而引发的异常 |
NotImplementedError | 方法没有实现而引发的异常 |
SyntaxError | 语法错误引发的异常 |
IndentationError | 代码缩进错误引发的异常 |
TabError | 空格和制表符混合使用引发的异常 |
TypeError | 使用不合适的类型执行运算引发的异常 |
ValueError | 使用不合适的参数值引发的异常 |
Python中的异常使用继承结构创建,这种设计方式非常灵活。可以在异常处理程序中捕获基类异常,也可以捕获子类异常。Python使用try…expect语句捕获异常,异常类型定义在try子语句的后面。
**注意:**如果在except子句后将异常类型设置为“Exception”,异常处理程序将捕获处程序中断外的所有异常。因为Exception类是其他异常类的基类。
try…except的使用方法
try…except语句用于处理问题语句,捕获可能出现的异常.try子句中的代码放置可能出现异常的语句,except子句中的代码块处理异常。当异常出现时,Python会自动生成1个异常对象。该对象包括异常的具体信息以及异常 种类和错误位置。
演示用try…except语句捕获IOError异常
try:
open("hello.txt", "r") #文件不存在将触发 IOError异常
except IOError:
print("文件不存在")
except:
print("程序异常")
print("继续执行")
try…finally的使用方法
try…except语句后还可以添加1个finally子句。finally子句的作用与Java中的finally字句类似,无论异常是否发生,finally字句都会被执行。所有finally字句通常用语关闭因异常不能释放的系统资源。
演示用使用finally
try:
f = open("hello.txt", "r") #文件不存在将触发 IOError异常
try:
print(f.read(5))
except:
print("读文件错误")
finally:
print("释放资源")
f.close()
except:
print("文件不存在")
**注意:**由于Python动态语言的特性,因此,要在某个代码块中使用同一级其他代码块中定义的变量,可以考虑以嵌套的方式或全局变量来实现。
使用raise抛出异常
当程序中出现错误,Python会自动引发异常,也可以通过raise语句显式的引发异常。一旦执行了raise语句,raise语句后的代码将不能被执行。
raise语句的使用方法
### raise语的使用方法
try:
s = None
if s is None: #判断变量s的值是否为空
print("s 是空对象")
raise NameError #使用 raise语句手动抛出 NameError异常
print(len(s))
except TypeError:
print("空对象没有长度")
自定义异常
Python允许程序员自定义异常类型,用于描述Python异常体系中没有涉及的异常情况。自定义异常必须继承Exception类。自定义异常按照命名规范以“Error”结尾,显式的告诉程序员该类是异常类。自定义异常使用raise语句引发,而且只能通过手工方式触发。
## 自定义异常的使用方法
from __future__ import division
class DivisionExptcion(Exception): #自定义异常
def __init__(self, x, y):
Exception.__init__(self, x, y)
self.x = x
self.y = y
if __name__ == "__main__":
try:
x = 3
y = 2;
if x%y > 0:
print(x/y)
raise DivisionExptcion(x, y)
except DivisionExptcion as div:
print("DivisionException:x/y = %.2f"%(div.x/div.y))
assert语句的使用方法
assert语句用于检测某个条件表达式四是否为真。assert语句又称为断言语句,即assert认为检测的表达式永远为真。if语句中的条件判断都可以使用assert语句检测。例图。检测某个元组中的个数是否大于1。如果assert断言失败,会引发AssertionError异常:
# ### assert语句的使用
# t = ("hello")
# assert len(t) >= 1
# t = ("hello")
# assert len(t) == 1
### 使用assert语句仿写 if语句
t = ("hello")
#assert len(t) < 1 , "检测程度不对"
try:
assert len(t) < 1 , "检测程度不对"
print("结果为真")
except AssertionError:
print("结果为假")
assert语句可以用于编写某个函数的时候,判断函数形参的数据范围,如果形参数据结果不对可以出发AssertionError异常来提示用户数据不对的原因。
异常信息
程序执行时,Python将会产生traceback对象,用于记录异常信息和当前程序的状态。traceback对象先记录主程序的状态,然后记录format()中的状态,最后记录函数中的状态,当函数出现异常时,traceback对象将输出记录的信息。
当程序产生异常时会输出异常信息,获取异常信息的方法可以使用try…expect语句。
### 捕获异常信息
import sys
try:
x = 10/0
except Exception as e:
print(e)
except:
print("程序异常")