美文网首页
python 10天快速教程 Day9

python 10天快速教程 Day9

作者: XaviSong | 来源:发表于2020-07-16 19:44 被阅读0次

本节重点

  1. IO
  2. 序列化
  3. 可迭代对象与迭代器
  4. 生成器
  5. 多线程

一、包

定义:

通俗理解为带有多个模块的文件夹,只不过文件夹中有__ init __.py文件,包裹、管理模块。

1、导入包中的模块
# 类比导入模块时的方式
# 方式一
import package.first
import package.second

# 方式二
from package import first as one
from package import second

# 方式三
from package import * # 导入包中所有模块
'''
可通过__init__.py 中限定导入模块:__all__ = ["first","second"]
'''
2、直接导入包
import package
package.first.show()
'''
python2中需要在__init__.py中添加
from package import first
from package import second
python3貌似不用
'''
3、使用包模块中的代码:
package.first.show()
package.first.show_msg()
4、设置包模块的别名
import package.first as one
one.show()
two.show_msg()

二、IO

目的:小批量数据先在内存中处理,再进行持久化(硬盘、数据库等)

1、stringIO
from io import StringIO
str_io = io.StringIO() # 获取对象

# 写入数据
str_io.write("hello")
str_io.write("word")

# 获取内存中全部数据
content = str_io.getvalue()
print(content)

# 设定对象指针
str_io.seek(0)
result = str_io.read() # 默认全部读取,接受参数表示读取字节数
print(result)
'''
helloword
helloword
'''
2、BytesIO
from io import BytesIO
byte_io = io.BytesIO()
# 编码写入二进制数据
byte_io.write("syp".encode("utf-8"))
data = byte_io.getvalue()
print(data)
# 解码读取二进制数据
result = data.decode("utf-8")
print(result)
'''
b'syp'
syp
'''

三、序列化

定义

把内存数据保存到本地,可以做到数据持久化

1、pickle

通用序列化模块,可序列化任何数据

import pickle
# 序列化
mylist = [{"name":"syp","age":22},{"name":"dsy","age":22}]
file = open("mylist.serialize","wb") # 后缀
pickle.dump(mylist, file) # 打包序列化
file.close()

# 反序列化
file = open("mylist.serialize","rb")
my_list = pickle.load(file)
print(my_list)
file.close()

# 对类对象的序列化,本质上就是序列化其属性
class Student:
    def __init__(self,name,age):
        super().__init__()
        self.name = name
        self.age = age
stu  = Student("syp",22)
file = open("stu.txt","wb")
pickle.dump(stu,file)
file.close()
file = open("stu.txt","rb")
my_list = pickle.load(file)
print(my_list.name,my_list.age)
file.close()
2、json

json序列化:只支持部分数据类型(列表、字典、int......),不支持自定义数据类型,比如自定义类,但是可以保存类的属性 json.dump(stu.__ dict __)。

import json
mylist = [{"name":"syp","age":22},{"name":"dsy","age":22}]
file = open("mylist.txt","w",encoding="utf-8")
json.dump(mylist,file)
file.close()
file = open("mylist.txt","r",encoding="utf-8")
mylist = json.load(file)
print(mylist)
'''
[{'name': 'syp', 'age': 22}, {'name': 'dsy', 'age': 22}]
'''

直接json序列化一个类对象会报错

class Student:
    def __init__(self,name,age):
        super().__init__()
        self.name = name
        self.age = age
stu = Student("syp",22)
file = open("mylist1.txt","w",encoding="utf-8")
json.dump(stu,file) # 报错
file.close()
'''
TypeError: Object of type Student is not JSON serializable
'''

但是可以只序列化其属性:

json.dump(stu.__dict__,file)
'''
{'name': 'syp', 'age': 22}
'''

四、可迭代对象

1、定义:

通俗理解为,for循环遍历取值的对象就是可迭代对象(列表、元组、字符串、集合、range),统一特征是具有__ iter __方法。

判断对象是否是可迭代对象

from collections import Iterable
result = isinstance([1,2,3],Iterable)
print(result)

# 判断对象是否为指定类型
result = isinstance([1,2,3],tuple)
print(result)

# 特征:可迭代对象都有__iter__方法
# 查看可迭代对象的所有方法
result = dir([1,2,3])
print(result)

'''
True
False
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
'''
2、迭代器
实现一个可迭代对象:

自定义一个类,并在类中重写iter和next方法,创建对象。

作用:

可以用数据位置获取下一个位置的值。

好处:

节省内存,不用每次将全部数据读入内存

class Myiterable(object):
    def __init__(self):
        super().__init__()
        self.mylist = [1,2,3,4,5]
        self.current_index = 0
    
    # 重写方法
    def __iter__(self):
        return self

    def __next__(self):
        if self.current_index < len(self.mylist):
            result = self.mylist[self.current_index]
            self.current_index += 1
            return result
        else:
            raise StopIteration # 抛出异常,停止迭代
myiter = Myiterable()
result = isinstance(myiter, Iterable)
print(result)
'''
True
'''

print(next(myiter))
print(next(myiter))
'''
1
2
'''
# 可用for循环打印出全部的数据
for value in myiter:
    print(value)
'''
1
2
3
4
5
'''
3、生成器
定义:

特殊迭代器,for循环遍历,自动停止迭代。不会一开始保存所有数据,而是实时计算出结果。而迭代器在已经存好数据的容器中不断取值。

result = (x for x in range(4))
print(result,type(result))
value = next(result)
print(value)
value = next(result)
print(value)
value = next(result)
print(value)
'''
<generator object <genexpr> at 0x000001EE47771138> <class 'generator'>
0
1
2
'''
yield生成器:

出现yield关键字,暂停,返回结果。下次启动生成器在暂停位置继续,可返回多次值。

g = show_num()
result = next(g) # 第一次返回for循环中的第一个元素0
print(result)
result = next(g) # 第二次生成器继续for循环,返回下一个元素1
print(result)
result = next(g) # 返回2
print(result)
'''
0
1
2
'''

五、多线程

1、定义:

执行代码的分支,默认只有一个主线程,多个线程可同时执行。

2、应用场景:

百度网盘,多任务下载。

注意:python本质上没有多线程

3、示例:执行多线程
# 方法A与方法B为两个线程执行
import threading #使用threading模块
def methodA(count):
    for i in range(count):
        print("AA\n")
def methodB(count):
    for i in range(count):
        print("BB\n")
if __name__ == "__main__":
    subthread1 = threading.Thread(target=methodA,args=(10,)) # 创建子线程
    subthread2 = threading.Thread(target=methodB,kwargs={"count":5})
    subthread1.start() # 执行子线程
    subthread2.start()
'''
AA
AA
AABB
AA

AABB

AABB

AABB

AABB

AA
AA
'''

注意args接收的参数是元组形式,kwargs接收的是字典形式。

4、示例:线程守护

主线程结束时,子线程被直接销毁结束,运用到daemon参数。

import threading
import time
def methodA():
    print("inAA",threading.current_thread())
    print("这是在子线程中执行的")
    while True:
        print("AA")
        time.sleep(0.2)
if __name__ == '__main__':
    print("main",threading.current_thread())
    sub = threading.Thread(target=methodA)
    sub.setDaemon(True) # 设置守护线程,主线程退出会直接销毁子线程
    sub.start()
    time.sleep(1)
    print("over")
'''
这是在子线程中执行的
AA
AA
AA
AA
AA
over
AA
AA
AA
(子线程的无限循环被终止)
'''
5、公共资源的争夺

如下两个线程都对g_num进行增加,但是不能达到预期的效果

import threading
g_num = 0
def sum1():
    global g_num
    for i in range(1000000):
        g_num+=1
    print("sum1",g_num)

def sum2():
    global g_num
    for i in range(1000000):
        g_num+=1
    print("sum2",g_num)

if __name__ == "__main__":
    first = threading.Thread(target = sum1)
    second = threading.Thread(target = sum2)
    first.start()
    second.start()
'''
sum2 1047819
sum1 1220658
'''

增加互斥锁来解决这个问题:

要对公共资源进行操作,必须先取得该资源上的锁,没有锁就不可以访问,当其他线程占用锁的时候不能抢夺,必须等其释放锁之后来获得锁。更详细的锁概念可以参考操作系统的相关书籍。

示例:互斥锁:
import threading
lock = threading.Lock() # 获得锁对象

g_num = 0
def sum1():
    lock.acquire() # 获得锁
    global g_num
    for i in range(1000000):
        g_num+=1
    lock.release() # 释放锁
    print("sum1",g_num)

def sum2():
    lock.acquire() # 获得锁
    global g_num
    for i in range(1000000):
        g_num+=1
    lock.release() # 释放锁
    print("sum2",g_num)

if __name__ == "__main__":
    first = threading.Thread(target = sum1)
    second = threading.Thread(target = sum2)
    first.start()
    second.start()
'''
sum1 1000000
sum2 2000000
'''

上一篇:python 10天快速教程 Day8
下一篇:python 10天快速教程 Day10

相关文章

  • Python 快速教程(网络)

    注:采转归档,自己学习查询使用 Python 快速教程(网络01):原始Python服务器Python 快速教程(...

  • Python 文档手册

    Python 官方文档 Vamei老师-Python快速教程 廖雪峰老师-Python教程 笨办法学Python ...

  • Python 快速教程(Django)

    注:采转归档,自己学习查询使用 Python 快速教程(Django01):初试天涯Python 快速教程(Dja...

  • 首次简书日记_Python资料相关

    Vamei的Python快速教程 廖雪峰的入门教程 简明 Python 教程 实验楼Python学习路径: 系统的...

  • Python 快速教程(进阶篇)

    注:采转归档,自己学习查询使用 Python 快速教程(进阶篇01): 词典Python 快速教程(进阶篇02):...

  • Python 快速教程(深入篇)

    注:采转归档,自己学习查询使用 Python 快速教程(深入篇01):特殊方法与多范式Python 快速教程(深入...

  • 初级知识0

    1. Python Python 教程 Python笔记(jupyter) 快速学会python 2.Matplo...

  • Python 快速教程(标准库)

    注:采转归档,自己学习查询使用 Python 快速教程(标准库):走马观花Python 快速教程(标准库):学习准...

  • Python 快速教程(基础篇)

    注:采转归档,自己学习查询使用 Python 快速教程(基础篇01):Hello WorldPython 快速教程...

  • Python 快速教程(补充篇)

    注:采转归档,自己学习查询使用 Python 快速教程(补充篇01): Python的序列的方法Python 快速...

网友评论

      本文标题:python 10天快速教程 Day9

      本文链接:https://www.haomeiwen.com/subject/dgumhktx.html