1.常见编码占用的字节数
英文字母:
字节数 : 1;编码:GB2312
字节数 : 1;编码:GBK
字节数 : 1;编码:GB18030
字节数 : 1;编码:UTF-8
中文汉字:
字节数 : 2;编码:GB2312
字节数 : 2;编码:GBK
字节数 : 2;编码:GB18030
字节数 : 3;编码:UTF-8
For example
>>> n="你好"
#使用utf-8解码[存储是按照16进制存储]
>>> n.encode("utf-8")
b'xe4xbdxa0xe5xa5xbd'
#使用gbk解码[存储是按照16进制存储]
>>> n.encode("gbk")
b'xc4xe3xbaxc3'
#使用utf-8解码
>>> b'xe4xbdxa0xe5xa5xbd'.decode("utf-8")
'你好'
#使用gbk解码
>>> b"xc4xe3xbaxc3".decode("gbk")
'你好'
字节换算
8bit = 1byte(字节) [8个二进制位等于一个字节]
1024byte = 1kbyte
1024kbyte= 1mbyte
1024mbyte= 1gbyte
1024gbyte= 1tbyte
2.集合
集合
:无序、不重复的序列
常见集合操作
#设置一个空的集合
collection=set()
#将列表转换成集合
collection=set(list)
#添加元素
set.add()
#清空集合
set.clear()
#浅拷贝
set.copy()
#集合比较:set1中存在set2中不存在
set1.difference(set2)
#集合比较:去掉集合中的交集
set1.symmetric_difference(set2)
#集合比较:set1中存在set2中不存在,结果更新至set1中
set1.difference_update(set2)
#集合比较:去掉集合中的交集,结果更新至set1中
set1.symmetric_difference_update(set2)
#集合比较:获取集合的交集
set1.intersection(set2)
#集合比较:获取集合的交集并更新至set1
set1.intersection_update(set2)
#集合比较:判断是否有交集:如果没有交集返回True,有交集则返回False
set1.isdijoint(set2)
#两个集合做并集
set1.union(set2)
#批量添加集合
set1.update()
#删除集合中的元素,不存在不报错
set.disard()
#删除集合中的元素,不存在报错
set.remove()
#随机删除集合中的元素(集合是无序的)
set.pop()
应用举例
- collection=set()
#设置一个空的集合
>>> collection=set()
>>> collection
set()
>>> type(collection)
<class 'set'>
- collection=set(list)
#将一个可迭代的序列转换成集合
>>> list=[1,2,3,4,5,6]
>>> collection=set(list)
>>> collection
{1, 2, 3, 4, 5, 6}
>>> type(collection)
<class 'set'>
- set.add()
>>> collection={1,2,3,4,5,}
#添加一个测试元素
>>> collection.add("test")
>>> collection
{1, 2, 3, 4, 5, 'test'}
- set.clear()
>>> collection={1,2,3,4,5,}
#清空集合
>>> collection.clear()
>>> collection
set()
- set.copy()
>>> collection={1,2,3,4,5,}
#内置函数copy为浅拷贝,只能拷贝第一层
>>> collection1=collection.copy()
>>> id(collection),id(collection1)
(140126401338056, 140126401034952)
- set1.difference(set2)
>>> collection1={1,2,3,4,5,}
>>> collection2={4,5,6,7,8,}
#获取集合1中存在集合2中不存在的元素
>>> collection1.difference(collection2)
{1, 2, 3}
- set1.symmetric_difference(set2)
>>> collection1={1,2,3,4,5,}
>>> collection2={4,5,6,7,8,}
#去掉两个集合的并集
>>> collection1.symmetric_difference(collection2)
{1, 2, 3, 6, 7, 8}
- set1.difference_update(set2)
>>> collection1={1,2,3,4,5,}
>>> collection2={4,5,6,7,8,}
#集合1中存在集合2中不存在,更新至集合1中
>>> collection1.difference_update(collection2)
>>> collection1
{1, 2, 3}
- set1.symmetric_difference_update(set2)
>>> collection1={1,2,3,4,5,}
>>> collection2={4,5,6,7,8,}
#去掉两个集合的并集
>>> collection1.symmetric_difference_update(collection2)
>>> collection1
{1, 2, 3, 6, 7, 8}
- set1.intersection(set2)
>>> collection1={1,2,3,4,5,}
>>> collection2={4,5,6,7,8,}
#获取集合1与集合2中的交集
>>> collection1.intersection(collection2)
{4, 5}
- set1.intersection_update(set2)
>>> collection1={1,2,3,4,5,}
>>> collection2={4,5,6,7,8,}
#获取集合1与集合2中的交集并更新至集合1中
>>> collection1.intersection(collection2)
>>> collection1
{4, 5}
- set1.isdijoint(set2)
>>> collection1={1,2,3,4,5,}
>>> collection2={4,5,6,7,8,}
#判断是否有交集,如果没有交集返回True,有交集则返回False
>>> collection1.isdisjoint(collection2)
False
- set1.union(set2)
>>> collection1={1,2,3,4,5,}
>>> collection2={4,5,6,7,8,}
#做2个集合的并集
>>> collection1.union(collection2)
{1, 2, 3, 4, 5, 6, 7, 8}
- set1.update()
>>> collection={1,2,3,4,5,}
#添加集合(添加的内容为可迭代的序列)
>>> collection.update([1,3,5,6,7,9])
>>> collection
{1, 2, 3, 4, 5, 6, 7, 9}
- set.discard()
>>> collection={1,2,3,4,5,}
#删除集合中的元素有则直接删除
>>> collection.discard(5)
#删除集合中的元素无则不报错
>>> collection.discard(6)
>>> collection
{1, 2, 3, 4}
- set.remove()
>>> collection={1,2,3,4,5,}
#删除集合中的元素有则不报错
>>> collection.remove(5)
#删除集合中的元素无则报错
>>> collection.remove(6)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 6
- set.pop()
>>> collection={"Alex","Bill","Yorick","Eric"}
#随机删除集合中的元素(因为集合是无序的)
>>> collection.pop()
'Alex'
>>> collection.pop()
'Bill'
>>> collection.pop()
'Eric'
3.集合的练习
描述:第一次获取内存插槽中的内存及内存大小[#槽位 : 大小]
old_dict={
"#1":8,
"#2":4,
"#4":2,
}
描述:第二次获取内存插槽中的内存及内存大小[#槽位 : 大小]
new_dict={
"#1":4,
"#2":4,
"#3":2,
}
需求分析
- 应该删除哪几个槽位
old_dict存在,new_dict中不存在
new_set=set(new_dict.keys())
old_set=set(old_dict.keys())
#取old_set中存在new_set中不存在的key
old_set.difference(new_set)
- 应该更新哪几个槽位
old_dict存在,new_dict中不存在
new_set=set(new_dict.keys())
old_set=set(old_dict.keys())
#取new_set中存在old_set中不存在的key
new_set.difference(old_set)
- 应该增加哪几个槽位
new.dict中存在,old_dict中不存在
new_set=set(new_dict.keys())
old_set=set(old_dict.keys())
#取new_set中存在old_set中也存在的
update_set = old_set.intersection(new_set)
4.函数与面向对象编程间的对比
背景
:一直以来的Python操作都是面向过程编程,即根据业务逻辑从上到下实现功能其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处
For example
while True:
if cpu利用率 > 90%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
if 硬盘使用空间 > 90%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
if 内存占用 > 80%:
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
重复代码较多,通过函数重写如下
def 发送邮件(内容):
#发送邮件提醒
连接邮箱服务器
发送邮件
关闭连接
while True:
if cpu利用率 > 90%:
发送邮件('CPU报警')
if 硬盘使用空间 > 90%:
发送邮件('硬盘报警')
if 内存占用 > 80%:
发送邮件('内存报警')
对于上述的两种实现方式,通过函数重写的重用性和可读性都比面向过程要好,这就是函数式编程和面向过程编程的区别
- 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
- 面向对象:对函数进行分类和封装,让开发“更快更好更强...”
5.函数的定义
def fuction(parameter):
......
fuciton body
......
return value
函数的定义主要有如下要点:
- def:表示函数的关键字
- 函数名(fuction):函数的名称,日后根据函数名调用函数
- 函数体(fuction body):函数体具体要做的工作例如计算、发送邮件等操作
- 参数(parameter):为函数体提供数据
- 返回值(return value):当函数执行完毕后,可以给调用者返回数据。
For example
#发送邮件
def sendmail():
#模块的导入
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
#设置邮件内容[可以书写html等]
msg = MIMEText('邮件内容', 'plain', 'utf-8')
#来自谁
msg['From'] = formataddr(["from",'xxxxxxxx@163.com'])
#发送给谁
msg['To'] = formataddr(["to",'xxxxxxxx@qq.com'])
#邮件主题
msg['Subject'] = "测试Python"
#smtp服务器
server = smtplib.SMTP("smtp.163.com", 25)
#邮件的账号及授权码
server.login("xxxxxxxxx@163.com", "********")
#发送邮件服务
server.sendmail('xxxxxxxx@163.com', ['xxxxxxxx@qq.com',], msg.as_string())
#服务退出
server.quit()
#返回发送成功
return True
6.函数的返回值
返回值
:返回值函数中的一个功能模块,该功能能够确认函数执行的结果,通过返回值告知调用者它的执行情况
For example
#!/usr/bin/env python
#_*_ coding:utf-8 _*_
#__author__="Yorick"
import os
def exist():
#如果文件存在返回true,如果不存在返回false
if os.path.exists("sendmail.py"):
return True
else:
return False
value=exist()
#针对返回值做如下判断
if value==True:
print("congratulations")
else:
print("error")
7.函数的参数
为什么要使用参数?
For example :不使用参数
#!/usr/bin/env python
#_*_ coding:utf-8 _*_
#__author__="Yorick"
import os,sys
def move_A_file():
os.popen("mv /Data/A.db /Data/back/A.db.back")
def move_B_file():
os.popen("mv /Data/B.db /Data/back/B.db.back")
def move_C_file():
os.popen("mv /Data/C.db /Data/back/C.db.back")
if sys.argv[1] == "A.db":
move_A_file()
if sys.argv[1] == "B.db":
move_B_file()
if sys.argv[1] == "C.db":
move_C_file()
For example :使用参数
#!/usr/bin/env python
#_*_ coding:utf-8 _*_
#__author__="Yorick"
import os,sys
def move_file(parameter):
os.popen("mv /Data/%s /Data/back/%s.back"(parameter,parameter))
if sys.argv[1] == "A.db":
move_file("A.db")
if sys.argv[1] == "B.db":
move_file("B.db")
if sys.argv[1] == "C.db":
move_file("C.db")
- 函数的形参:函数定义好的为形参
- 函数的实参:调用函数时传入为实参[注意:函数实参传入到形参中为引用]
7.1.普通参数
严格按照顺序,将实际参数赋值给形式参数
For example 1
def fuction(par1,par2):
print(par1)
print(par2)
fuction(10,20)
result
10
20
7.2.默认参数
必须从形参的末尾开始设置
For example 1
def fuction(par1,par2=3000):
print(par1)
print(par2)
fuction(10)
result
10
3000
For example 2
#字符串的格式化
print("i am {0} ,age {1}".format("alex","18"))
print("i am {0} ,age {1}".format(*["alex","18"]))
7.3.指定参数
将实际参数赋值给指定的形式参数
For example 1
def fuction(par1,par2):
print(par1)
print(par2)
fuction(par1=2000,par2=666) #fuction(par2=666,par1=2000)
result [指定参数,实参的位置可以不按照顺序写]
2000
666
For example 2
print("i am {name} ,age {age}".format(name="alex",age="18"]))
print("i am {name} ,age {age}".format(**{name:"alex",age:"18"}))
7.4.动态参数
* 默认将传入的参数,全部放置在元组中
** 默认将传入的参数,全部放置在字典中
For example 1
def fuction(*args):
print(args)
print(type(args))
#默认参数传参
fuction(2000,666)
result
(200,600)
#将实传入的参转变成元组,供调取使用
<type 'tuple'>
For example 2
def fuction(*args):
print(args)
print(type(args))
#实参传入时可以使用“*+可迭代集合”(元组、列表、集合、字符串等)
fuction(*(2000,666)) #fuction(*[2000,666])/fuction(*{2000,666})/fuction(*"2000666")
result
(200,600)
#将实传入的参转变成元组,供调取使用
<type 'tuple'>
For example 3
def fuction(**kwargs):
print(kwargs)
print(type(kwargs))
#可以指定参数传参
fuction(par1=2000,par2=600)
result
{'par2': 600, 'par1': 2000}
#将指定传参转换成字典,供调取使用
<type 'dict'>
For example 4
def fuction(**kwargs):
print(kwargs)
print(type(kwargs))
#可以使用“**+字典”将整个字典传入函数调用中
fuction(**{'par2': 600, 'par1': 2000})
result
{'par2': 600, 'par1': 2000}
#将指定传参转换成字典,供调取使用
<type 'dict'>
7.5.万能参数
动态参数组合使用
For example
def fuction(*args, **kwargs):
print(args,type(args))
print(kwargs,type(kwargs))
#既可以使用普通传参也可以使用指定传参
#注意:如果普通参数加指定参数传参普通参数需要写在前面
fuction(1,2,3,3,4,5,a=100,b=800)
result
#args接收到的元素转换成元组
((1, 2, 3, 3, 4, 5), <type 'tuple'>)
#kwargs接收到的元素转换成字典
({'a': 100, 'b': 800}, <type 'dict'>)
8.变量问题整理
- 全局变量:定义在全局中,任何函数与类都能调用并修改
- 局部变量:定义在函数只能,但是不能与其他函数公用的变量
- 作用域:当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是局部的,成为变量的作用域
- 变量调取顺序:当调用变量时,优先读函数体内的变量,如果函数体内没有查找全局变量
- 局部变量转变成全局变量:[global parameter] 局部变量名前加global即可将局部变量转变成全局变量
9.函数式编程
#格式优美的代码及注释
def login(username,password):
"""
用于用户登录
:username:账户
:password:密码
:True 成功
:False 失败
"""
f=open("db","r")
for line in f:
line_list = line.split("|")
if line_list[0] == username and line_list[1] == password:
return True
return False
def register():
f=open("db","a")
temp="
" + username + "|" + password
f.write(temp)
f.close
def main():
t=input("1:login 2:register:")
if t == "1":
user=input("input username:")
pwd=input("input password")
elif t == "2":
pass
r=login(user,pwd)
if r:
print("success")
else:
print("error")
main()
10.三元运算、三目运算
简单的if else判断
>>> name="Yorick"
#如果name等于Yorick则显示富有,否则显示穷
>>> describe = "rich" if name == "Yorick" else "poor"
>>> describe
'rich'
11.lambda表达式[简单函数return]
简单的函数返回值,默认return回显结果
For example 1
#赋值a1将 a1+100返回给对象调用
>>> result = lambda a1:a1+100
>>> result(12)
112
For example 2
#赋值a1,a2,a3为默认值将 a1+a2+a3返回给对象调用
>>> result = lambda a1,a2,a3=10000:a1+a2+a3
>>> result(100,1000)
11100
12.内置函数(part1)
#绝对值
abs()
#所有值都为真才为真
all()
#只要有一个值为真就为真
any()
#10进制转成二进制
bin()
#10进制转成八进制
oct()
#10进制转成十六进制
hex()
#布尔值
bool()
#字符转换成字节
bytes()
#字节转换成字符
str()
使用举例
- abs()
#数字的绝对值
>>> abs(-100)
100
>>> abs(100)
100
- bool()
#判断是真是假
>>> bool(0)
False
>>> bool(1)
True
>>> bool(2)
True
>>> bool("")
False
- all()
#所有为真才为真
>>> all('123')
True
>>> all([0, 1])
False
>>> all([1, 2])
True
- any()
#有一个为真即为真
>>> any('123')
True
>>> any([0, 1])
True
>>> any([0, ''])
False
- bin()
#0b表示10进制
>>> bin(10)
'0b1010'
- oct()
#0o表示10进制
>>> oct(10)
'0o12'
- hex()
#0x表示16进制
>>> hex(10)
'0xa'
- bytes()
#将字符转换成字节
>>> bytes("你好世界",encoding="utf-8")
b'xe4xbdxa0xe5xa5xbdxe4xb8x96xe7x95x8c'
- str()
#将字节转换成字符串
>>> str(b'xe4xbdxa0xe5xa5xbdxe4xb8x96xe7x95x8c',encoding="utf-8")
'你好世界'
13.内置函数(part2)
#对文件的操作
open()
#基本流程
①打开文件
op_file=open("file name","rwb+")
②操作文件
op_file.operation()
③关闭文件
op_file.close()
13.1.打开文件的方式
#打开data.db以只读的方式打开
op_file=open("data.db","r")
操作 | 操作权限 | 操作说明 |
---|---|---|
r | 只读 | 不支持写操作 |
w | 只写 | 不支持读操作,写之前需要先清空文件 |
x | 当文件存在时就报错 | 如果文件不存在就可以创建文件并写(不支持读,仅python3.0+支持该操作) |
a | 追加内容 | 文件最后方插入,不支持查看 |
rb | 只读字节文件 | 不支持写操作 |
wb | 只写字节文件 | 不支持读操作,写之前需要先清空文件 |
xb | 只写字节文件,当文件存在时就报错 | 如果文件不存在就可以创建文件并写(不支持读,仅Python3.0+支持该操作) |
ab | 只追加字节文件,追加内容 | 文件最后方插入,不支持查看 |
r+ | 可读可写 | 在末尾添加(文件中有位置指针,默认指针在文件的开头) |
w+ | 可读可写 | 先清空之后才能读 |
x+ | 可读可写 | 可以读操作(仅Python3.0+支持该操作) |
a+ | 可读可写 | 永远是在最后追加 |
13.2.操作文件的方式
#如果打开模式无b,则read,按照字符读取(字节)
op_file.read()
操作 | 操作说明 |
---|---|
op_file.read() | 读取全部内容 |
op_file.tell() | 获取当前指针位置 |
op_file.seek() | 指针跳转到指定位置 |
op_file.write() | 写数据 |
op_file.close() | 关闭文件 |
op_file.fileno() | 文件描述符 |
op_file.flush() | 强制刷新 |
op_file.readable() | 是否可读 |
op_file.seekable() | 是否可以移动指针 |
op_file.readline() | 只读取第一行(移动指针到第二行) |
op_file.turncate() | 截断数据,指针后内容清空 |
op_file.readlines() | 按照 每行读取 |
13.3.关闭文件
#关闭文件的方式一
f.close()
#关闭文件的方式二
with open("data.db","r") as op_file:#打开data.db文件赋值给变量op_file
operation(pass)
建议
:以后打开文件都使用with...as..这样就不用再写一行关闭了
For example
#把一个文件的前10行,添加到另一个文件
with open("xb","r",encoding="utf-8") as f1,open("db","r",encoding="utf-8") as f2:
times=0
for line in f1:
if times < 10:
f2.write(line)
times+=1
else:
break