python3基础-廖雪峰
一、编程基础
1.1 格式化输出
print("hello %s" %("wold"))
print("%s %s" %("hello","wold"))
#类似C语言,前后两个百分号
print("%d" %(23))
1.2 枚举类
from enum import Enum,unique
class Weekday(Enum):
Sun = 0
Mon = 1
Tue = 2
Wed = 3
Thu = 4
Fri = 5
Sat = 6
day1 = Weekday.Mon
print(day1)
print(day1.value)
1.3 输入
name = input()
1.4 数据类型
int = 23 #整形
float = 1.2e2 #浮点型
string = "aoce" #字符串
print('''haha
...heihei
...haha''')
bool = True
no = None
1.5 相同向量指向同一个内存
a = "hello"
b = a
a = "wold"
print(b)
#a和b指向的相同的内存,之前的忘了,这个不对
1.6 与或非运算
#and运算
print("and运算")
print(True and False)
print(False and False)
print(True and True)
#or运算
print("or运算")
print(True or True)
print(True or False)
print(False or False)
#or运算
print("or运算")
print(not True)
print(not False)
1.7 字符编码问题
#这里涉及到的是字符编码问题
#字符串在Python中是Unicode表示
#含有中文的str无法用ASCII编码
print(ord("a")) #97
print(ord("A")) #65
print(ord("杨")) #26472
print(chr(26472)) #杨
print("\u4e2d\u6587")
print(b"aoce")
#ASCII和utf-8
print("ABC".encode("ascii")) #b'ABC'
print('中文'.encode('utf-8')) #b'\xe4\xb8\xad\xe6\x96\x87'
#从网络或者磁盘上读取了字节流,读到的数据就是bytes
#bytes类型的用带b的前缀加引号表示
#把bytes变成str,用decode()方法
print(b'ABC'.decode('ascii'))
#避免乱码始终坚持UTF-8编码对str和bytes进行转换
1.8 for循环
#循环迭代列表和元组
names = ['a','b','c']
ages = (1,2,3)
for name in names:
print(name)
for age in ages:
print(age)
#1到10的整数之和
sum = 0
for x in [1,2,3,4,5,6,7,8,9,10]:
sum = sum + x
print(sum) #55
sum = 0
for x in range(11):
sum = sum + x
print(sum)
1.9 if...else语句
a = 3
if a == 3:
pass
else:
pass
b = 3
if b==2:
pass
elif b==3:
print("haha")
else:
pass
1.10 if语句
num = 23
if num >= 100:
print("haha")
else:
print("heihei")
1.11 while 循环
sum = 0
n = 99
while n > 0 :
sum = sum + n
n = n - 2
print(sum)
二、语法特点
2.1 递归函数
def fact(n):
if n==1:
return 1
return n*fact(n-1)
print(fact(10))
2.2 迭代
#迭代dict字典的key
l = {'a':1,'b':2,'c':3}
for key in l:
print(key)
#迭代dict字典的value
for value in l.values():
print(value)
#迭代字符串
for st in 'Aoce':
print(st)
#迭代list列表
for li in [1,2,3]:
print(li)
#list 索引-元素 迭代
for i, value in enumerate(['a','b','c']):
print(i, value)
#迭代tuple元组
for tu in ('a','b','c'):
print(tu)
#判断是否可迭代
from collections import Iterable
print(isinstance('abc', Iterable))
2.3 定义函数
def my_abs(x):
if not isinstance(x,(int,float)):
raise TypeError('bad operand type') #设置异常
if x>=0:
return x
else:
return -x
print(my_abs(-9))
2.4 关键字参数函数
def person(name,age,*a,**kw):
print('name:',name,'age:',age,'a=',a,'other:',kw)
person('aoce',24,'a','b',city='henan',job = 'student')
#**kw是关键字参数,输出是dict字典
#*a是可变参数,输出是tuple元组
2.5 类似字典的set
#提供一个 list作为输入的集合
s = set([1,2,3,3])
print(s) #{1, 2, 3}重复的会被删掉
#添加
s.add(4)
print(s)
#删除
s.remove(4)
print(s)
#set是个无序和无重复元素的集合,可以做数学上的交集、并集操作
2.6 列表生成器gengrator
#第一种创建generator
g = (x*x for x in range(10))
#打印generator
print(next(g)) #0
print(next(g)) #1
print(next(g)) #4
#对于generator 每次调用next() 都会计算出下一个值
#迭代generator
for n in g:
print(n) #9~81
#第二种定义generator的方法
#包含yield的函数是generator,每次调用next的时候执行,遇到yield返回,再次执行时从上次返回的yield语句处执行
def fib(max):
n,a,b = 0,0,1
while n < max:
yield b
a, b = b, a+b
n = n + 1
return 'done'
for i in fib(6):
print(i)
2.7 列表生成式
#生成[1,2,3,4,5,6,7]
li1 = list(range(1,7))
print(li1)
#生成[1,4,9,16]
li2 = [x*x for x in range(1,4)]
print(li2)
#仅偶数的平方
li3 = [x*x for x in range(1,4) if x%2 == 0]
print(li3)
#两层循环生成全排列
li4 = [m + n for m in 'ABC' for n in 'XYZ']
print(li4)
#两个变量生成list
d1 = {'x':'A','y':'B','z':'C'}
li5 = [k + '=' + v for k, v in d1.items()]
print(li5)
#前面是含有变量的具体形式,后面是对变量进行迭代
2.8 切片
#切片可以对列表、元组、字符串进行切片
#对list切片
a = [1,2,3,4,5]
n = a[0:2]
print(n)
#对tuple切片
b = (1,2,3,4)
i = b[0:2]
print(i)
#对Str切片
print('Aoce'[0:2])
2.9 数据类型转换
int('123')
int(12.34)
float('12.34')
str(123)
str(12.3)
bool(1)
bool('')
#函数名其实就是指向一个函数对象的引用,完全可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”
a = abs
print(a(-1)) #1
2.10 字符串的replace方法
str = "Aoce"
str = str.replace('A','a')
print(str) #aoce
2.11 dict字典
#字典以 key-value 的形式存储
soce = {'Michale':95,'Bob':75,'Tracy':85}
print(soce['Michale'])
#改变value的值
soce['Michale'] = 55
print(soce['Michale'])
#判断 key 是否存在
print('Michale' in soce) #True
print(soce.get('aoce')) #None
#删除字典里 key-value
soce.pop('Michale')
2.12 global 关键字
cont = 5
def A():
global cont
cont = 10
A()
print(cont)
2.13 list列表
#list列表
classmates = ["Michal",'Bob','Tracy']
len(classmates) #返回获取列表长度
classmates[0] #头部索引列表元素
classmates[-1] #尾部索引列表元素
classmates.append('Adam') #尾部追加元素
classmates.insert(1,'Jack') #指定位置插入元素
classmates.pop(1) #pop()函数默认删除末尾元素,加入索引值删除指定位置元素
teacher = ['aoce',123,['haha','heihei'],2.3] #基本类型加本身
2.14 math函数
print(abs(-23))
print(max(1,3,6,3,5,6,8))
2.15 tuple元组
#tuple一旦初始化就不能修改(安全)
classmates = ('Michale','Bob',['aoce',123])
#元组本身不能改变,但是元素可以包含列表
classmates[2][0] #来表示元组里的列表
三、面向对象
3.1 __slots__绑定属性
class Student(object):
__slots__ = ('name','age') #__slots__只对当前类起作用,对子类不起作用
aoce = Student()
aoce.name = 'Aoce'
3.2 __str__打印
class Student(object):
def __init__(self, name):
self.name = name
def __str__(self):
return 'Student object (name: %s)' % self.name
print(Student('Michale')) #Student object (name: Michale)
#使用__str__输出的信息更易懂,默认调用的输出方法是__repr__
3.3 @property装饰器
#作用:把类函数变成属性调用
class Student(object):
@property
def score(self):
return self.score
@score.setter
def score(self,value):
if not isinstance(value, int):
raise ValueError('score must be int')
if value < 0 or value > 100:
raise ValueError('score must between 0~100')
self.score = value
Aoce = Student()
3.4 错误处理
try:
a = 10/0 #语法错误,执行except,执行完后执行finally
print('try...')
except ZeroDivisionError as e:
print('except...')
finally:
print('finally...')
print('end...')
3.5 多继承
class Run(object):
pass
class Fly(object):
pass
class Bird(Run,Fly):
pass
bage = Bird()
#多继承的好处,可以把各类需要的方法继承下来,需要什么就继承什么
3.6 继承与多态
#继承
class Animal(object):
def run(self):
print("animal is running")
class Dog(Animal):
def wang(self):
print("Dog is wangwang")
def runtwice(Animal):
Animal.run()
Animal.run()
dog = Dog()
dog.run()
#多态 多态就是父类可以有多个子类
dog.runtwice() #多态就是类似9行和10行调用父类的函数
3.7 类变量访问权限
class Animal(object):
#双下划线的是特殊变量,可以直接访问
def __init__(self,name,age,sorce):
self.__name = name #self.__name是类本身的变量
self.__age = age #外部无法访问.__name变量
self.sorce = sorce #可以从外部直接访问
animal = Animal("aoce",23,93)
print(animal.sorce)
3.8 类和实例
#2020年1月21日18:34:54
#类的基本形式如下面的Student类
class Student(object):
"""docstring for Student"""
def __init__(self, name,sorce):
super(Student, self).__init__()
self.name = name
self.sorce = sorce
aoce = Student('aoce',93)
print(aoce.name)
3.9 判断数据类型
#isinstance()函数判断是否是指定数据类型,或则是否在其父类链上
class Animal(object):
def run(self):
print("Animal is running")
dog = Animal()
print(isinstance(dog,object))
print(isinstance(dog,Animal))
#type()获取对象的数据类型
print(type(dog))
#dir()获取对象的所有属性和方法
print(dir(Animal))
3.10 设置 、获取、查找对象属性
class Animal(object):
def __init__(self,name):
self.name = name
dog = Animal('dog')
print(hasattr(dog,'name')) #查看是否有该属性
setattr(dog,'name','Aoce') #设置属性参数
getattr(dog,'name') #获取该属性值
3.11 GUI
from tkinter import *
class Application(Frame):
def __init__(self,master=None):
Frame.__init__(self,master)
self.pack()
self.createWidgets()
def createWidgets(self):
self.helloLabel = Label(self,text='Hello,wold')
self.helloLabel.pack()
self.quitButton = Button(self,text='Quit', command=self.quit)
self.quitButton.pack()
app = Application()
app.master.title('Hello Wold')
app.mainloop()
3.12 map函数和reduce函数
#2020年1月23日11:27:26
#1. map()函数接收两个参数,函数和Iterable
#2. map()将传入的函数依次作用到序列的每个元素,并把结果作为新的
# Iterator 返回。
#3. list()函数将整个序列都计算出来并返回一个list
def f(x):
return x*x
r = list(map(f,[1,2,3,4,5]))
print(r)
#reduce()函数可以把函数返回的结果和序列的下一个单元累加
from functools import reduce
def add(x,y):
return x+y
b = reduce(add, [1,2,3])
print(b)
3.13 metaclass元类
#基本用不到
3.14 Pillow处理图片
from PIL import Image
im = Image.open('text.png')
print(im.format, im.size, im.mode)
3.15 UDP协议服务器
s =socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#绑定端口
s.bind(('123.0.0.1', 9999))
print('Bind UDP on 9999...')
while True:
# 接收数据:
data, addr = s.recvfrom(1024)
print('Received from %s:%s.' % addr)
s.sendto(b'Hello, %s!' % data, addr)
3.16 UDP协议客户端
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Michael', b'Tracy', b'Sarah']:
# 发送数据:
s.sendto(data, ('127.0.0.1', 9999))
# 接收数据:
print(s.recv(1024).decode('utf-8'))
s.close()
3.17 urlib的Get
from urllib import request
with request.urlopen('http://www.bilibili.com') as f:
data = f.read()
print('Status:',f.status,f.reason)
for k, v in f.getheaders():
print('%s:%s' % (k,v))
print('Data:', data.decode('utf-8'))
四、流、序列化、进线程
4.1 操作文件和目录
#其实操作系统提供的命令只是简单地调用了操作系统提供的接口函数
import os
os.name #'nt'也就是windows系统
os.environ #返回所有环境变量
os.environ.get('Path') #返回Path环境变量
# 查看当前目录的绝对路径:
os.path.abspath('.') #返回的是E:\PYTHON
# 在某个目录下创建一个新目录,首先把新目录的完整路径表示出来:
os.path.join('e:/PYTHON/day04', 'testdir')
# 然后创建一个目录:
os.mkdir('e:/PYTHON/day04/testdir')
#删掉一个目录:
os.rmdir('e:/PYTHON/day04/testdir')
4.2 读写闭UTF-8文件
#一般的读写文件
f = open('E:\PYTHON\day04\小文件.txt','r')
print(f.read())
f.close()
#使用with语句不用close()
with open('E:\PYTHON\day04\小文件.txt','r') as d:
print(d.read())
#上面的read方法一次性读取文件,如果是大的配置文件,用readlines()
#d = open('E:\PYTHON\day04\多行文件.txt','r')
#for line in d.readlines():
# print(line.strip()) #把末尾的\n去掉
4.3 读GBK文件
f = open('E:\PYTHON\day04\小文件.txt','r',encoding='gbk',errors='ignore')#遇到错误的字符直接跳过
print(f.read())
f.close()
4.4 多线程MAC
import os
print('Process (%s) start...' % os.getpid())
pid = os.fork()
if pid == 0:
print('i am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
else:
print('i (%s) just created a child process (%s).' % (os.getpid(), pid))
#上述代码在Windows上无法运行
4.5 线程交替执行
#书上写的不详细,我靠
import threading
def T1():
for i in range(100):
local.acquire()
print("This is T1...")
try:
change_it(n)
finally:
lock.release()
def T1():
for i in range(100):
local.acquire()
print("This is T2...")
try:
change_it(n)
finally:
lock.release()
4.6 写文件
with open('E:\PYTHON\day04\小文件.txt','w') as f:
f.write('I am Aoce!') #会删除原文件内容
f.close()
4.7 序列化
#们把变量从内存中变成可存储或传输的过程称之为序列化
import pickle
d = dict(name='Aoce',age=23,score=93) #生成一个字典
pickle.dumps(d) #【序列化】pickle.dump()直接把对象序列化后写入一个 file-like Object
f = open('dump.txt','wb') #写入
pickle.dump(d,f)
f.close() #保存二进制文件
f = open('dump.txt','rb')
d = pickle.load(f) #反序列化
f.close
print(d)
4.8 BytesIO
from io import BytesIO
f = BytesIO()
f.write('中文'.encode('utf-8'))
print(f.getvalue())
#输出的是经过 UTF-8 编码的 bytes
4.9 JSON进阶
#把class转换成dict,然后转成JSON
import json
class Student(object):
def __init__(self,name,age,score):
self.name = name
self.age = age
self.score = score
def JsonClass(std):
return {
'name':std.name,
'age':std.age,
'score':score
}
aoce = Student('aoce','23',93)
print(json.dumps(aoce, default=lambda obj: obj.__dict__)) #OK
print(json.dumps(aoce,default=JsonClass)) #Student 实例首先被 student2dict()函数转换成 dict,然后再被顺利序列化为 JSON
4.10 JSON序列化
#如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如 XML,但更好的方法是序列化为 JSON
#下面是Python 对象变成一个 JSON
import json
d = dict(name='Bob', age=20, score=88)
json.dumps(d) #dumps()方法返回的是一个str
json.loads(d) #load()或者loads()方法把之前的JSON反序列化
#JSON的编码是UTF-8和Python的编码一样,所以传回的str可以互相转换
#可序列化对象dict、list、str、int\float、bool、None
4.11 multiprocessing模块的process类进程
from multiprocessing import Process
import os
#子进程要执行的代码
def run_proc(name):
print('Run child process %s (%s)...' % (name, os.getpid()))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Process(target=run_proc, args=('test',))
print('Child process will start.')
p.start() #方法启动
p.join() #等待子进程结束后再往下运行
print('Child process end.')
4.12 StringIO读写内存中的String
from io import StringIO
f = StringIO()
f.write('hello wold!')
print(f.getvalue())
f.close()
4.13 task_master
import random, time, queue
from multiprocessing.managers import BaseManager
# 发送任务的队列:
task_queue = queue.Queue()
# 接收结果的队列:
result_queue = queue.Queue()
# 从 BaseManager 继承的 QueueManager:
class QueueManager(BaseManager):
pass
# 把两个 Queue 都注册到网络上, callable 参数关联了 Queue 对象:
QueueManager.register('get_task_queue', callable=lambda: task_queue)
QueueManager.register('get_result_queue', callable=lambda:result_queue)
# 绑定端口 5000, 设置验证码'abc':
manager = QueueManager(address=('', 5000), authkey=b'abc')
# 启动 Queue:
manager.start()
# 获得通过网络访问的 Queue 对象:
task = manager.get_task_queue()
result = manager.get_result_queue()
# 放几个任务进去:
for i in range(10):
n = random.randint(0, 10000)
print('Put task %d...' % n)
task.put(n)
# 从 result 队列读取结果:
print('Try get results...')
for i in range(10):
r = result.get(timeout=10)
print('Result: %s' % r)
# 关闭:
manager.shutdown()
print('master exit.')
4.14 task_worker
import time, sys, queue
from multiprocessing.managers import BaseManager
# 创建类似的 QueueManager:
class QueueManager(BaseManager):
pass
# 由于这个 QueueManager 只从网络上获取 Queue,所以注册时只提供名字:
QueueManager.register('get_task_queue')
QueueManager.register('get_result_queue')
# 连接到服务器,也就是运行 task_master.py 的机器:
server_addr = '127.0.0.1'
print('Connect to server %s...' % server_addr)
# 端口和验证码注意保持与 task_master.py 设置的完全一致:
m = QueueManager(address=(server_addr, 5000), authkey=b'abc')
# 从网络连接:
m.connect()
# 获取 Queue 的对象:
task = m.get_task_queue()
result = m.get_result_queue()
# 从 task 队列取任务,并把结果写入 result 队列:
for i in range(10):
try:
n = task.get(timeout=1)
print('run task %d * %d...' % (n, n))
r = '%d * %d = %d' % (n, n, n*n)
time.sleep(1)
result.put(r)
except Queue.Empty:
print('task queue is empty.')
# 处理结束:
print('worker exit.')
4.15 threading线程模块
#主线程实例的名字叫 MainThread,子线程的名字在创建时指定,我们用 LoopThread 命名子线程。
import time, threading
#新线程执行的代码
def loop():
print('thread %s is running...' % threading.current_thread().name) #current_thread()函数,它永远返回当前线程的实例
n = 0
while n < 5:
n = n + 1
print('thread %s >>> %s' % (threading.current_thread().name, n))
time.sleep(1)
print('thread %s ended.' % threading.current_thread().name)
#代码开始执行
print('thread %s is running...' % threading.current_thread().name)
t = threading.Thread(target = loop,name='LoopThread') #创建线程(执行函数+线程名称)
t.start() #线程开始
t.join() #线程运行至结束
print('thread %s ended.' % threading.current_thread().name)
""" 下面是输出结果:
thread MainThread is running...
thread LoopThread is running...
thread LoopThread >>> 1
thread LoopThread ended.
thread LoopThread >>> 2
thread LoopThread ended.
thread LoopThread >>> 3
thread LoopThread ended.
thread LoopThread >>> 4
thread LoopThread ended.
thread LoopThread >>> 5
thread LoopThread ended.
thread MainThread ended.
"""
4.16 ThreadLoad
import threading
local_school = threading.local() # 创建全局 ThreadLocal 对象:每个Thread都可以对它读取student属性
def process_student():
std = local_school.student # 获取当前线程关联的 student:
print('Hello, %s (in %s)' % (std, threading.current_thread().name))
def process_thread(name):
local_school.student = name # 绑定 ThreadLocal 的 student:
process_student()
t1 = threading.Thread(target= process_thread, args=('Alice',),name='Thread-A') # target调用的函数,args传递的参数,name线程的名字
t2 = threading.Thread(target= process_thread, args=('Bob',),name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()
"""
1. threading.local可以理解为全局变量,每个线程local_school.student可以任意读写且不互相干扰
2. ThreadLocal 最常用的地方就是为每个线程绑定一个数据库连接
3. threading.local也可以理解为dict
总结:一个 ThreadLocal 变量虽然是全局变量,但每个线程都只能读写自己线
程的独立副本,互不干扰。ThreadLocal 解决了参数在‘一个线程中’各个函
数之间互相传递的问题。
该程序的输出结果:
Hello, Alice (in Thread-A)
Hello, Bob (in Thread-B)
"""
五、正则表达式、图片、图形界面
5.1 图片处理
from PIL import Image, ImageFilter
im = Image.open('E:\PYTHON\day05正则表达式\est.jpg')
im2 = im.filter(ImageFilter.BLUR)
im2.save('hel.jpg','jpeg')
5.2 GUI程序
from tkinter import*
class Application(Frame):
def __init__(self,master=None):
Frame.__init__(self,master)
self.pack()
self.createWidgets()
def createWidgets(self):
self.helloLabel = Label(self,text='hello wold!')
self.helloLabel.pack()
self.quitButton = Button(self,text="Quit",command=self.quit)
self.quitButton.pack()
app = Application()
app.master.title('hello wold!')
app.mainloop()
"""
在 GUI 中,每个 Button、Label、输入框等,都是一个 Widget。Frame
则是可以容纳其他 Widget 的 Widget,
pack()方法把 Widget 加入到父容器中,并实现布局。pack()是最简单的
布局,grid()可以实现更复杂的布局。
在 createWidgets()方法中,我们创建一个 Label 和一个 Button,当 Button
被点击时,触发 self.quit()使程序退出。
"""
5.3 Re模块
import re
if re.match(r'aa',"hahaaoce"):
print("OK")
else:
print("Error")
六、网络
6.1 服务器WSGI
from wsgiref.simple_server import make_server # 从 wsgiref 模块导入:
from WSGI服务器响应接口 import application # 导入我们自己编写的 application 函数:
httpd = make_server('', 8000, application) # 创建一个服务器,IP 地址为空,端口是 8000,处理函数是 application:
print('Serving HTTP on port 8000...')
httpd.serve_forever() # 开始监听 HTTP 请求:
6.2 基于TCP的Socket
import socket
s = socket.socket(socket.AF_INET6,socket.SOCK_STREAM) # ipv6协议,面向流的TCP协议
s.connect(('www.sina.com.cn',80)) #指定域名和服务器端口
#发送数据
s.send(b'GET / HTTP/1.1\r\nHost:www.sina.com.cn\r\nConnection:close\r\n\r\n')
#接收数据
buffer = [] #接收数据的容器
while True:
d = s.recv(1024) #一次最多接收的字节数
if d: #直到返回空字节
buffer.append(d) #数据写入d中
else:
break
data = b''.join(buffer)
s.close()
#把HTTP片头和网页分离。把HTTP打印出来,网页内容保存到文件
header, html = data.split(b'\r\n\r\n', 1)
print(header.decode('utf-8'))
#接收数据写入文件
with open('sina.html','wb') as f:
f.write(html)
"""
1. 创建 Socket 时,AF_INET 指定使用 IPv4 协议,如果要用更先进的 IPv6,
就指定为 AF_INET6。SOCK_STREAM 指定使用面向流的 TCP 协议,这样,一
个 Socket 对象就创建成功,但是还没有建立连接。
2. 80 端口是 Web 服务的标准端口,SMTP 服务是 25 端口,FTP 服务是 21 端口,等等。
端口号小于 1024 的是 Internet 标准服务的端口,端口号大于 1024 的,
可以任意使用
"""
6.3 TCP服务器
import socket,threading
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) #创建基于IPV4的TCP协议的socket
s.bind(('127.0.0.1',9999)) #将主机和端口绑定到套接字上
s.listen(5) #设置并启动TCP监听器
print("Waiting...")
while True:
sock,addr = s.accept() #被动接受 TCP 客户端连接,一直等待直到连接到达(阻塞)
t = threading.Thread(target=tcplink,args=(sock,addr))
t.start()
def tcplink(sock,addr):
print('Accept new connection from %s:%s...' % addr)
scok.send(b'welcome')
while True:
data = sock.recv(1024)
time.sleep(1)
if not data or data.decode('utf-8') == 'exit':
break
sock.send(('Hello, %s!' % data).encode('utf-8'))
sock.close()
print('Connection from %s:%s closed.' % addr)
6.4 TCP客户端
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建基于V4的TCP连接
s.connect(('127.0.0.1', 9999)) #把地址和端口绑定到套接字
print(s.recv(1024).decode('utf-8')) #recv()接收TCP消息
for data in [b'Michael', b'Tracy', b'Sarah']:
s.send(data) #发送数据
print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()
6.5 UDP服务器
#和客户端运行成功
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# 绑定端口:
s.bind(('127.0.0.1', 9999))
while True:
# 接收数据:
data, addr = s.recvfrom(1024)
print('Received from %s:%s.' % addr)
s.sendto(b'Hello, %s!' % data, addr)
6.6 UDP客户端
#和UDP服务端运行成功
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
for data in [b'Michael', b'Tracy', b'Sarah']:
# 发送数据:
s.sendto(data, ('127.0.0.1', 9999))
# 接收数据:
print(s.recv(1024).decode('utf-8'))
s.close()
6.7 WSGI服务器响应接口
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
body = '<h1>Hello, %s!</h1>' % (environ['PATH_INFO'][1:] or 'web')
return [body.encode('utf-8')]
"""
上面的 application()函数就是符合 WSGI 标准的一个 HTTP 处理函数,
它接收两个参数:
environ:一个包含所有 HTTP 请求信息的 dict 对象;
start_response:一个发送 HTTP 响应的函数。
"""
七、爬虫
## 1、requests.get()的content和text区别
resp.text返回的是Unicode型的数据。(str)
resp.content返回的是bytes型也就是二进制的数据。(str)
resp.json()返回的是json格式数据。(dict)
如果你想取文本,可以通过r.text。
如果想取图片,文件,则可以通过r.content。
x = eval(resp.text)
y = resp.json()
x == y