day1
输入输出
a = input("输入字符串:")
b = int(input("输入int:"))
print(type(a))
print(type(b))
#格式化输出
print('{} {} {}'.format('aaron',18,'teacher'))
print('{1} {0} {1}'.format('aaron',18,'teacher'))
print('{name} {age} {job}'.format(job='teacher',name='aaron',age=18))
input 默认输入为string。
字符串的索引与切片
# 0是列表中第一个元素的索引,-1 是列表中最后一个元素的索引,满足顾头不顾尾的原则
a = "ABCDEF"
print(a[0:-1])#结果为 ABCDE
字符串处理
words = "beautiful is better than ugly."
words.capitalize() #首字母大写
words.swapcase() #大小写翻转
words.title() #每个单词的首字母大写
# 内容居中,总长度,空白处填充 center(总长度,"填充符号")
ret = a.center(20,"*")
# startswith 判断是否以...开头
# endswith 判断是否以...结尾
# return 布尔值
a.startswith("a")
a.endswith("j")
a.startswith('sdj',2,5)
a.endswith('ado',7,10)
# split 以什么分割,最终形成一个列表此列表不含有这个分割的元素。
ret = words.split(' ')
ret = words.rsplit(' ',2) # 加数字指定分割次数
# strip
a = '****asdasdasd********'
print(a.strip('*')) #清除所有该元素
print(a.lstrip('*')) #清除左侧所有该元素
print(a.rstrip('*')) #清除右侧所有该元素
# replace
print(words.replace('e','a',2)) # 字符串从左向右开始,把e替换成a,一共替换两次
print(words.isalnum()) #字符串由字母或数字组成
print(words.isalpha()) #字符串只由字母组成
print(words.isdigit()) #字符串只由数字组成
列表处理(增删改查)
li = [1,'a',2,'d',4]
li.insert(0,22) # 按照索引去增加
li.append('ddd') # 增加到最后
li.extend(['q,a,w']) # 迭代的去增
li.extend(['q,a,w','das']) # 迭代的去增
a = li.pop(1) # 按照位置去删除,有返回值
print(a) #删除成功后a = 1
del li[1:3] # 按照位置去删除,也可切片删除没有返回值。
li.remove('f') # 删除指定字符。
li.clear() #清空列表
li[1] = 'aaa' #修改指定字符
li[2:3] = [3,'e']#修改对应切片字符
元组(不可修改)
tuple = (1, 2, 3, [1, 4, 7])
print(tuple)
tuple[3][2] = 100#可以修改元组里的列表中的数据
print(tuple)
字典(增删改查)
dic = {"age": 18, "name": "aaron"}
dic['li'] = ["a", "b", "c"]
dic.setdefault('k', 'v')# 在字典中添加键值对时,如果指定的键已经存在则不做任何操作,如果原字典中不存在指定的键值对,则会添加。
#删除
dic['name'] = 'demo'
dic_pop = dic.popitem()
# 随机删除字典中的某个键值对,将删除的键值对以元祖的形式返回
dic.pop()#随机删除
dic.pop('age')
dic_pop = dic.pop('sex', '查无此项')#如存在该键,则值为对应是数值,否则为后面的默认值。
dic_clear = dic.clear()# 清空字典
#修改
dic['li'] =["a","b"]
dic = {"age":18, "name":"aaron", 'sex':'male'}
dic2 = {"age":30, "name":'demo'}
dic2.update(dic)# 将dic所有的键值对覆盖添加(相同的覆盖,没有的添加)到dic2中
#查询
a1 = dic['age'] #若无该键,无返回值
print(a1)
a2 = dic.get('ll', 'qqq')#若无该键,有返回值
print(a2)
集合
集合是无序的,不重复,确定性的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的。以下是集合最重要的两点:
- 去重,把一个列表变成集合,就自动去重了。
- 关系测试,测试两组数据之前的交集、差集、并集等关系。
set1 = set({1,2,'barry'})
set2 = {1,2,'barry'}
set1 = {'abc','def',123,'asdas'}# add()函数的参数只能接收可哈希数据类型,即不可变数据类型,比如整型、浮点型、元组、字符串
set1.add('qwer')
set1.update('A')#update:迭代着增加
set1.pop()#随机删除
del set1#删除集合
set1 | set2# | 并集,& 交集,- 差集,^ 反交集
s = frozenset(set1)#frozenset不可变集合,让集合变成不可变类型<class 'frozenset'>
s.add(7) # 不可以修改,会报错
按存储空间的占用分(从低到高)
- 整型
- 字符串
- 集合:无序,即无序存索引相关信息
- 元组:有序,需要存索引相关信息,不可变
- 列表:有序,需要存索引相关信息,可变,需要处理数据的增删改
- 字典:无序,需要存key与value映射的相关信息,可变,需要处理数据的增删改
流程控制之 --if
False:[],{},()
True:其他
"""
if 条件:
满足条件执行代码
else:
if条件不满足就走这段
"""
流程控制之 --while
"""
while 条件:
循环体
"""
循环中止语句
break
用于完全结束一个循环,跳出循环体执行循环后面的语句
continue
continue 只是终止本次循环
day2
文件操作
1.打开文件
2.读写文件
3.关闭文件
# 1. 打开 - 文件名需要注意大小写
file = open("README") #变量 = open("文件名", "访问方式")
# 2. 读取
text = file.read()
print(text)
# 3. 关闭
file.close()
text1 = file1.readline().strip()#按行读写
f=open('a.txt','r',encoding='utf-8')#按规定编码打开文件
with
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:#with方法:open(文件名) as 变量
data=read_f.read()
write_f.write(data)
文件操作方法
def close(self, *args, **kwargs): # real signature unknown
关闭文件
pass
def fileno(self, *args, **kwargs): # real signature unknown
文件描述符
pass
def flush(self, *args, **kwargs): # real signature unknown
刷新文件内部缓冲区
pass
def isatty(self, *args, **kwargs): # real signature unknown
判断文件是否是同意tty设备
pass
def read(self, *args, **kwargs): # real signature unknown
读取指定字节数据
pass
def readable(self, *args, **kwargs): # real signature unknown
是否可读
pass
def readline(self, *args, **kwargs): # real signature unknown
仅读取一行数据
pass
def seek(self, *args, **kwargs): # real signature unknown
指定文件中指针位置
pass
def seekable(self, *args, **kwargs): # real signature unknown
指针是否可操作
pass
def tell(self, *args, **kwargs): # real signature unknown
获取指针位置
pass
def truncate(self, *args, **kwargs): # real signature unknown
截断数据,仅保留指定之前数据
pass
def writable(self, *args, **kwargs): # real signature unknown
是否可写
pass
def write(self, *args, **kwargs): # real signature unknown
写内容
pass
def __getstate__(self, *args, **kwargs): # real signature unknown
pass
def __init__(self, *args, **kwargs): # real signature unknown
pass
@staticmethod # known case of __new__
def __new__(*args, **kwargs): # real signature unknown
""" Create and return a new object. See help(type) for accurate signature. """
pass
def __next__(self, *args, **kwargs): # real signature unknown
""" Implement next(self). """
pass
def __repr__(self, *args, **kwargs): # real signature unknown
""" Return repr(self). """
pass
函数
def getnum(a):#定义函数getnum,传入参数a
#函数内容
global b #在函数中调用全局变量
b*=b
rutrun b#函数返回值,若不声明则为None
闭包
内部函数包含对外部作用域而非全剧作用域变量的引用,该内部函数称为闭包函数
例子:在调用某个函数的内部函数时,使用闭包可以直接访问到内部函数,如果多次调用时,就只需要运行一次该函数。
from urllib.request import urlopen
def func():
content = urlopen('http://myip.ipip.net').read().decode('utf-8')
def get_content():
return content
return get_content
code = func()
content = code()
print(content)
content2 = code()
print(content2)
装饰器
让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。 装饰器的应用场景:比如插入日志,性能测试,事务处理,缓存等等场景。
def a(x):
def a1():
print("c")
x()
print("a")
return a1
@a #b=a(b) 让b函数获得了a函数中的内容
def b():
print("b")
b() #其中b函数的运行顺序为a函数中函数的顺序
#b.__name__ = a1
day3
迭代器
我们已经知道可以对list、tuple、str等类型的数据使用for...in...的循环语法从其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代。在python的数据类型中,只有整形不可迭代。
# 字符串、列表、元组、字典、集合都可以被for循环,说明他们都是可迭代的
from collections.abc import Iterable
l = [1, 2, 3, 4]
t = (1, 2, 3, 4)
d = {1: 2, 3: 4}
s = {1, 2, 3, 4}
print(isinstance(l, Iterable))
print(isinstance(t, Iterable))
print(isinstance(d, Iterable))
print(isinstance(s, Iterable))
生成器
一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值,但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。
def genrator_func1():
a = 1
print('将a赋值')
yield a
b = 2
print('将b赋值')
yield b
g1 = genrator_func1()
print(g1,next(g1))
print(next(g1))
推导式
把列表解析的[]换成()得到的就是生成器表达式
列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
Python不但使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。例如, sum函数是Python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议,所以,我们可以直接这样计算一系列值的和
variable = [out_exp_res for out_exp in input_list if out_exp == 2] out_exp_res: 列表生成元素表达式,可以是有返回值的函数。 for out_exp in input_list: 迭代input_list将out_exp传入out_exp_res表达式中。 if out_exp == 2: 根据条件过滤哪些值可以。
合并大小写对应的value值,将k统一成小写
dic1 = {'a':1,'b':2,'y':1, 'A':4,'Y':9}
dic2 = {k.lower():dic1.get(k.lower(),0) + dic1.get(k.upper(),0) for k in dic1.keys()}
print(dic2)
内置函数
截止到python版本3.6.2,现在python一共为我们提供了68个内置函数。
匿名函数
函数名 = lambda 参数 :返回值,实参
- 参数可以有多个,用逗号隔开
- 匿名函数不管逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值
- 返回值和正常的函数一样可以是任意数据类型
calc = lambda n: n ** n
print(calc(10))
递归
汉诺塔小游戏:
def move(n, a, b, c):
if n == 1:
print(a, "-->", c)
else:
move(n - 1, a, c, b)
print(a, "-->", c)
move(n - 1, b, a, c)
move(3, "a", "b", "c")
递归:高级
def search(num,l,start=None,end=None):
start = start if start else 0
end = len(l)-1 if end is None else end
mid = (end - start)//2 + start
if start > end:
return None
elif l[mid] > num :
return search(num,l,start,mid-1)
elif l[mid] < num:
return search(num,l,mid+1,end)
elif l[mid] == num:
return mid
ret = search(18,l)
print(ret)
day4
模块与包
模块调用:
import module_name as name #module_name为模块名,name为调用名,可省略。
import sys, os, re #import可以同时导入多个模块
常用模块
序列化模块
json模块:
Json模块提供了四个功能:dumps、dump、loads、load。
dump和load为对文件的操作。
import json
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = json.dumps(dic)
# 序列化:将一个字典转换成一个字符串
print(type(str_dic),str_dic)
dic2 = json.loads(str_dic)
print(type(dic2),dic2)
# 反序列化:将一个字符串格式的字典转换成一个字典
list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
str_dic = json.dumps(list_dic)
print(type(str_dic),str_dic)
list_dic2 = json.loads(str_dic)
print(type(list_dic2),list_dic2)
pickle模块
用于python特有的类型 和 python的数据类型间进行转换。
import pickle
dic = {'k1':'v1','k2':'v2','k3':'v3'}
str_dic = pickle.dumps(dic)
print(str_dic)
dic2 = pickle.loads(str_dic)
print(dic2)
import time
struct_time = time.localtime(time.time())
print(struct_time)
f = open('pickle_file','wb')
pickle.dump(struct_time,f)
f.close()
f = open('pickle_file','rb')
struct_time2 = pickle.load(f)
print(struct_time2.tm_year)
os模块
re模块(正则表达式)
url = '<img width="100" alt="(.*?)" src="(.*?)" class="">'
day5
异常处理
try:
a = 'a'
a = int(a)
except:
print('发生错误')
垃圾回收机制
如何管理内存:
如何优化内存:
day6
面向对象
class Light:#创建类
def __init__(self, color):#类的初始化属性
self.color = color
def changecolor(self):#类的方法
pass
class Redlight(Light):#创建类redlight继承light
def changecolor(self):
print('红灯停')
if __name__ == "__main__":
ludeng = Redlight('red')#实例化
ludeng.changecolor()#调用类的方法
print(ludeng.__dict__)
继承
父类私有化
- 父类的对象不能直接访问
__num2
属性 - 父类的对象不能在
demo
方法内访问__num2
属性 - 父类的对象可以在
demo
方法内,调用父类的test
方法 - 父类的
test
方法内部,能够访问__num2
属性和__test
方法
class a:
def __eat(self):
print('eat')
class b(a):
pass
b = b()
b.eat()
封装
- 封装 是面向对象编程的一大特点
- 面向对象编程的 第一步 —— 将 属性 和 方法 封装 到一个抽象的 类 中
- 外界 使用 类 创建 对象,然后 让对象调用方法
- 对象方法的细节 都被 封装 在 类的内部
class Foo:
def __init__(self,name,age):
self.name = name
self.age = age
def detail(self):
print(self.name)
print(self.age)
obj1 = Foo('chensong',18)
obj2 = Foo('aaron',16)
print(obj1.name)
print(obj2.age)
# 通过对象直接调用被封装的内容
obj1.detail()
obj2.detail()
# 通过self间接调用被封装的内容
多态
鸭子类型
class Duck:
def quack(self):
print("嘎嘎叫!")
def fly(self):
print("扑哧扑哧的飞!")
class Person:
def quack(self):
print("我喜欢跟鸭子一样嘎嘎叫")
def fly(self):
print("我也喜欢跟鸭子一样飞")
def make_it_quack_and_fly(obj):
obj.quack()
obj.fly()
duck = Duck()
person = Person()
make_it_quack_and_fly(duck)
make_it_quack_and_fly(person)。
类的约束
- 提取⽗类. 然后在⽗类中定义好⽅法. 在这个⽅法中什么都不⽤⼲. 就抛⼀个异常就可以了. 这样所有的⼦类都必须重写这个⽅法. 否则. 访问的时候就会报错.
- 使⽤元类来描述⽗类. 在元类中给出⼀个抽象⽅法. 这样⼦类就不得不给出抽象⽅法的具体实现. 也可以起到约束的效果.
- 先用第一种方法解决问题
class Payment:
"""
此类什么都不做,就是制定一个标准,谁继承我,必须定义我里面的方法。
"""
def pay(self,money):
raise Exception("你没有实现pay方法")
class QQpay(Payment):
def pay(self,money):
print('使用qq支付%s元' % money)
class Alipay(Payment):
def pay(self,money):
print('使用阿里支付%s元' % money)
class Wechatpay(Payment):
def fuqian(self,money):
print('使用微信支付%s元' % money)
def pay(obj,money):
obj.pay(money)
a = Alipay()
b = QQpay()
c = Wechatpay()
pay(a,100)
pay(b,200)
pay(c,300)
super()
继承类调用被继承类中的方法。
class A:
def f1(self):
print('in A f1')
def f2(self):
print('in A f2')
class Foo(A):
def f1(self):
super().f2()
print('in A Foo')
obj = Foo()
obj.f1()
day7
socket
- TCP(Transmission Control Protocol)
- 可靠的、面向连接的协议(eg:打电话)、传输效率低全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:Web浏览器;文件传输程序。
- UDP(User Datagram Protocol)
- 不可靠的、无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文(数据包),尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统 (DNS);视频流;IP语音(VoIP)。
TCP
服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束
import socket
# 初始化格式如下
socket.socket(socket_family,socket_type,protocal=0)
# socket_family 可以是 AF_UNIX 或 AF_INET。socket_type 可以是 SOCK_STREAM 或 SOCK_DGRAM。protocol 一般不填,默认值为 0。
# 获取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 获取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 由于 socket 模块中有太多的属性。我们在这里破例使用了'from module import *'语句。使用 'from socket import *',我们就把 socket 模块里的所有属性都带到我们的命名空间里了,这样能 大幅减短我们的代码。
# 例如
tcpSock = socket(AF_INET, SOCK_STREAM)
UDP
服务器端先初始化Socket,然后与端口绑定(bind),recvform接收消息,这个消息有两项,消息内容和对方客户端的地址,然后回复消息时也要带着你收到的这个客户端的地址,发送回去,最后关闭连接,一次交互结束
服务端:
import socket
udp_sk = socket.socket(type=socket.SOCK_DGRAM) #创建一个服务器的套接字
udp_sk.bind(('127.0.0.1',9000)) #绑定服务器套接字
msg,addr = udp_sk.recvfrom(1024)
print(msg)
udp_sk.sendto(b'hi',addr) # 对话(接收与发送)
udp_sk.close() # 关闭服务器套接字
客户端:
import socket
ip_port=('127.0.0.1',9000)
udp_sk=socket.socket(type=socket.SOCK_DGRAM)
udp_sk.sendto(b'hello',ip_port)
back_msg,addr=udp_sk.recvfrom(1024)
print(back_msg.decode('utf-8'),addr)
粘包
1.接收方没有及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一小部分,服务端下次再收的时候还是从缓冲区拿上次遗留的数据,产生粘包)
2.发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据也很小,会合到一起,产生粘包)
struct模块
import struct
# 将一个数字转化成等长度的bytes类型。
ret = struct.pack('i', 18334)
print(ret, type(ret))
# 通过unpack反解回来 返回一个元组回来
ret1 = struct.unpack('i',ret)[0]
print(ret1, type(ret1))
# 但是通过struct 处理不能处理太大
multiprocess模块
multiprocess.process模块介绍
创建进程:
import os
from multiprocessing import Process
def f(x):
print('子进程id:',os.getpid(),'父进程id:',os.getppid()) #查看子进程id:os.getpid(),查看父进程id:os.getppid()
return x*x
if __name__ == '__main__':
print('主进程id: ',os.getpid())
p_lst = []
for i in range(5):
p = Process(target=f,args=(i,))
p.start()
守护进程
import os
import time
from multiprocessing import Process
class Myprocess(Process):
def __init__(self,person):
super().__init__()
self.person = person
def run(self):
print(os.getpid(),self.name)
print('%s正在和女主播聊天' %self.person)
if __name__ == '__main__':
p=Myprocess('陈松')
p.daemon=True #一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行
p.start()
time.sleep(10) # 在sleep时查看进程id对应的进程
print('主')