python知识小结(2)
来源:互联网 发布:mysql truncate函数 编辑:程序博客网 时间:2024/06/03 17:08
StringIO和BytesIO
StringIO
很多时候,数据读写不一定是文件,也可以在内存中读写。
StringIO顾名思义就是在内存中读写str。
要把str写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可:
>>> from io import StringIO>>> f = StringIO()>>> f.write('hello')5 # 返回的是写入的字符串的长度>>> f.write(' ')1>>> f.write('world!')6>>> print(f.getvalue())hello world!getvalue()方法用于获得写入后的str。要读取StringIO,可以用一个str初始化StringIO,然后,像读文件一样读取:>>> from io import StringIO>>> f = StringIO('Hello!\nHi!\nGoodbye!')>>> while True:... s = f.readline() # 按照行的形式 从内存中读取数据... if s == '':... break... print(s.strip())...Hello!Hi!Goodbye!
BytesIO
BytesIO
StringIO操作的只能是str,如果要操作二进制数据,就需要使用BytesIO。
BytesIO实现了在内存中读写bytes,我们创建一个BytesIO,然后写入一些bytes:
>>> from io import BytesIO>>> f = BytesIO()>>> f.write('中文'.encode('utf-8'))6>>> print(f.getvalue())b'\xe4\xb8\xad\xe6\x96\x87'请注意,写入的不是str,而是经过UTF-8编码的bytes。和StringIO类似,可以用一个bytes初始化BytesIO,然后,像读文件一样读取:>>> from io import BytesIO>>> f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')>>> f.read()b'\xe4\xb8\xad\xe6\x96\x87'
通过 os 来获取环境变量中的值
os.environ.get(key, default) 从环境变量中获取到需要的值, 如果没有这个值, 就返回 设定的默认的值
使用 os.path 来操作文件的目录
os.path.abspath() 获取项目下的绝对的路径
os.path.split(文件的名称) 返回的结果是一个 列表 列表中的 元素是 文件的名称 和 文件的后缀名称
第一个使用的是 os.path.split()os.path.split(os.path.join(os.path.abspath(''), "1111.txt"))返回的内容: ('D:\\test\\练习', '1111.txt')第二个使用的是 os.path.splitext() 返回的是文件的名称和后缀os.path.splitext(os.path.join(os.path.abspath(''), "1111.txt"))返回的内容: ('D:\\test\\练习\\1111', '.txt')这些合并、拆分路径的函数并不要求目录和文件要真实存在,它们只对字符串进行操作。# 对文件重命名:>>> os.rename('test.txt', 'test.py')# 删掉文件:>>> os.remove('test.py')
copyfile() 函数的使用
幸运的是shutil模块提供了copyfile()的函数,你还可以在shutil模块中找到很多实用函数,它们可以看做是os模块的补充
一行代码搞定当前目录下的所有的文件夹
os.list.dir() # 获取到当前目录下面的所有的文件和文件夹>>> [x for x in os.listdir('.') if os.path.isdir(x)]['.lein', '.local', '.m2', '.npm', '.ssh', '.Trash', '.vim', 'Applications', 'Desktop', ...]列出当前文件下面所有的采用的是以指定文件后缀结尾的文件>>> [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']['apis.py', 'config.py', 'models.py', 'pymonitor.py', 'test_db.py', 'urls.py', 'wsgiapp.py']
序列化的操作
pickle
pickle 序列化后的操作 只能使用Python 语言进行使用
>>> import pickle>>> d = dict(name='Bob', age=20, score=88)>>> pickle.dumps(d)b'\x80\x03}q\x00(X\x03\x00\x00\x00ageq\x01K\x14X\x05\x00\x00\x00scoreq\x02KXX\x04\x00\x00\x00nameq\x03X\x03\x00\x00\x00Bobq\x04u.'pickle.dumps()方法把任意对象序列化成一个bytes,然后,就可以把这个bytes写入文件。或者用另一个方法pickle.dump()直接把对象序列化后写入一个file-like Object:和json的 功能是一样的 但是就是 json 是通用的 但是 pickle 只能Python 语言 才能进行使用Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。
json 序列化的 进阶操作 使用json 序列化一个对象
使用 json 序列化一个类的对象
import jsonclass Student(object): def __init__(self, name, age, score): self.name = name self.age = age self.score = scores = Student('Bob', 20, 88)print(json.dumps(s))这样直接的进行序列化的时候 是会出现错误的Traceback (most recent call last): ...TypeError: <__main__.Student object at 0x10603cc50> is not JSON serializablejson中的 可选参数default 可以传入一个函数 来先把累对象 转换成一个 字典可选参数default就是把任意一个对象变成一个可序列为JSON的对象,我们只需要为Student专门写一个转换函数,再把函数传进去即可:def student2dict(std): return { 'name': std.name, 'age': std.age, 'score': std.score }这样,Student实例首先被student2dict()函数转换成dict,然后再被顺利序列化为JSON:>>> print(json.dumps(s, default=student2dict)){"age": 20, "name": "Bob", "score": 88}不过,下次如果遇到一个Teacher类的实例,照样无法序列化为JSON。我们可以偷个懒,把任意class的实例变为dict:print(json.dumps(s, default=lambda obj: obj.__dict__))因为通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量。也有少数例外,比如定义了__slots__的class同样的道理,如果我们要把JSON反序列化为一个Student对象实例,loads()方法首先转换出一个dict对象,然后,我们传入的object_hook函数负责把dict转换为Student实例:def dict2student(d): return Student(d['name'], d['age'], d['score'])运行结果如下:>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'>>> print(json.loads(json_str, object_hook=dict2student))<__main__.Student object at 0x10cd3c190>打印出的是反序列化的Student实例对象。使用json 序列化一个日期的的对象 明天记得完成
dict_ 可以把类中的对象的属性转换成一个字典的形式
class Student(): def __init__(self, name, age, gender): self.name = name self.age = age self.gender = genderdemo = Student("xixi", 20, 1).__dict__print(type(demo))print(demo)输出结果: <class 'dict'> {'name': 'xixi', 'age': 20, 'gender': 1}
使用 subprocess 来创建子进程
一、subprocess以及常用的封装函数
运行python的时候,我们都是在创建并运行一个进程。像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序。在Python中,我们通过标准库中的subprocess包来fork一个子进程,并运行一个外部的程序。
subprocess包中定义有数个创建子进程的函数,这些函数分别以不同的方式创建子进程,所以我们可以根据需要来从中选取一个使用。另外subprocess还提供了一些管理标准流(standard stream)和管道(pipe)的工具,从而在进程间使用文本通信。
subprocess.call()
父进程等待子进程完成
返回退出信息(returncode,相当于Linux exit code)
subprocess.check_call()
父进程等待子进程完成
返回0
检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性,可用try…except…来检查
多线程下 使用 lock 的
当多个程序同时修改一个数据的时候 就需要用到锁的概念,
使用 lock = threading.lock() 创建一个锁的对象
获取锁的对象采用的是 lock.acquire() 释放锁 采用的是 lock.release()
常用模块
- datetime 模块 2.
获取当前的时间>> from datetime import datetime>>> datetime.now()datetime.datetime(2017, 10, 12, 16, 36, 45, 179103)>>> now = datetime.now()>>> print(now)2017-10-12 16:36:59.643930>>> type(now)<class 'datetime.datetime'>设定指定的时间>>> time = datetime(2017, 10, 12, 16, 40)>>> print(time)2017-10-12 16:40:00
- datetime转换为timestamp
3.
>>> now.timestamp()1507797419.64393把timestamp 转换会 datetime的方法now = datetime.fromtimestamp(t)要把timestamp转换为datetime,使用datetime提供的fromtimestamp()方法:>>> from datetime import datetime>>> t = 1429417200.0>>> print(datetime.fromtimestamp(t))2015-04-19 12:20:00注意到timestamp是一个浮点数,它没有时区的概念,而datetime是有时区的。上述转换是在timestamp和本地时间做转换。本地时间是指当前操作系统设定的时区。例如北京时区是东8区,则本地时间:2015-04-19 12:20:00实际上就是UTC+8:00时区的时间:2015-04-19 12:20:00 UTC+8:00而此刻的格林威治标准时间与北京时间差了8小时,也就是UTC+0:00时区的时间应该是:2015-04-19 04:20:00 UTC+0:00timestamp也可以直接被转换到UTC标准时区的时间:>>> from datetime import datetime>>> t = 1429417200.0>>> print(datetime.fromtimestamp(t)) # 本地时间2015-04-19 12:20:00>>> print(datetime.utcfromtimestamp(t)) # UTC时间2015-04-19 04:20:00
字符串和 时间的转换
str转换为datetime
很多时候,用户输入的日期和时间是字符串,要处理日期和时间,首先必须把str转换为datetime。转换方法是通过datetime.strptime()实现,需要一个日期和时间的格式化字符串:
datetime.strptime(string, "%Y-%m-%d-%H") >>> from datetime import datetime>>> cday = datetime.strptime('2015-6-1 18:19:59', '%Y-%m-%d %H:%M:%S')>>> print(cday)2015-06-01 18:19:59
字符串’%Y-%m-%d %H:%M:%S’规定了日期和时间部分的格式
把datetime.now() 转换成str 字符串的方法
>>> now.strftime("%Y-%m-%d %H:%M:%S")'2017-10-12 16:36:59'
datetime 的加减操作
对日期和时间进行加减实际上就是把datetime往后或往前计算,得到新的datetime。加减可以直接用+和-运算符,不过需要导入timedelta这个类:
>>> from datetime import datetime, timedelta>>> now = datetime.now()>>> nowdatetime.datetime(2015, 5, 18, 16, 57, 3, 540997)>>> now + timedelta(hours=10)datetime.datetime(2015, 5, 19, 2, 57, 3, 540997)>>> now - timedelta(days=1)datetime.datetime(2015, 5, 17, 16, 57, 3, 540997)>>> now + timedelta(days=2, hours=12)datetime.datetime(2015, 5, 21, 4, 57, 3, 540997)
小结
datetime表示的时间需要时区信息才能确定一个特定的时间,否则只能视为本地时间。
如果要存储datetime,最佳方法是将其转换为timestamp再存储,因为timestamp的值与时区完全无关。
collections的使用
- 使用namedtuple创建一个指定属性的元组
>>> from collections import namedtuple>>> point = namedtuple("point", ['x', 'y'])>>> p = point(1, 2)>>> p.x1>>> p.y2>>> ppoint(x=1, y=2)同时满足这两种的实例>>> isinstance(p, point)True>>> isinstance(p, tuple)Truenamedtuple是一个函数,它用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素。这样一来,我们用namedtuple可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便。可以验证创建的Point对象是tuple的一种子类:
- 使用deque 来构建 双向的列表 list
使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:
>>> q = deque(['a', 'b', 'c'])>>> qdeque(['a', 'b', 'c'])>>> q.append('d')>>> qdeque(['a', 'b', 'c', 'd'])>>> q.append(1)>>> qdeque(['a', 'b', 'c', 'd', 1])>>> q.appendleft(2)>>> qdeque([2, 'a', 'b', 'c', 'd', 1])从左右边删除 但是里面不能带参数 list中的pop 是可以携带参数的 代表的是要删除那个索引下的元素>>> q.pop()1>>> q.popleft()2
- defaultdict
可以作为字典来使用, 当获取到的key 不存在的时候 返回一个默认的值 给 字典中的键统一的设定
defaultdict类的初始化函数接受一个类型作为参数,当所访问的键不存在的时候,可以实例化一个值作为
>>> dd1 = defaultdict(list)>>> dd1["key"][]>>> dd1["key1"] = 2>>> dd1["key1"]2
defaultdict类除了接受类型名称作为初始化函数的参数之外,还可以使用任何不带参数的可调用函数,到时该函数的返回结果作为默认值
>>> dd = defaultdict(lambda:' ')>>> dd["key"]''
注意默认值是调用函数返回的,而函数在创建defaultdict对象时传入。
除了在Key不存在时返回默认值,defaultdict的其他行为跟dict是完全一样的。
在参数中使用 * 或者 ** 是为了让这个指定的变量 进行解包操作
- Orderdict 实现一个有序的字典的方式
>>> from collections import OrderedDict>>> d = dict([('a', 1), ('b', 2), ('c', 3)])>>> d # dict的Key是无序的{'a': 1, 'c': 3, 'b': 2}>>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])>>> od # OrderedDict的Key是有序的OrderedDict([('a', 1), ('b', 2), ('c', 3)])注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:其他的操作和 普通的字典是没有什么区别的
- counter 计数器的使用
使用counter 可以完成 统计一个列表中出现重复的次数
from collections import Counter
c = Counter(sequence) 传入的是一个序列对象 可迭代的对象
c.most_common(n) 传入的参数是一个 整型, 是要获取到 前几个数据
源码中的一些简单实例:
'''Dict subclass for counting hashable items. Sometimes called a bag or multiset. Elements are stored as dictionary keys and their counts are stored as dictionary values. >>> c = Counter('abcdeabcdabcaba') # count elements from a string >>> c.most_common(3) # three most common elements [('a', 5), ('b', 4), ('c', 3)] >>> sorted(c) # list all unique elements ['a', 'b', 'c', 'd', 'e'] >>> ''.join(sorted(c.elements())) # list elements with repetitions 'aaaaabbbbcccdde' >>> sum(c.values()) # total of all counts 15 >>> c['a'] # count of letter 'a' 5 >>> for elem in 'shazam': # update counts from an iterable ... c[elem] += 1 # by adding 1 to each element's count >>> c['a'] # now there are seven 'a' 7 >>> del c['b'] # remove all 'b' >>> c['b'] # now there are zero 'b' 0 >>> d = Counter('simsalabim') # make another counter >>> c.update(d) # add in the second counter >>> c['a'] # now there are nine 'a' 9 >>> c.clear() # empty the counter >>> c Counter() Note: If a count is set to zero or reduced to zero, it will remain in the counter until the entry is deleted or the counter is cleared: >>> c = Counter('aaabbc') >>> c['b'] -= 2 # reduce the count of 'b' by two >>> c.most_common() # 'b' is still in, but its count is zero [('a', 3), ('c', 1), ('b', 0)]
struct 模块的使用
Python提供了一个struct模块来解决bytes和其他二进制数据类型的转换。
struct的pack函数把任意数据类型变成bytes:
hashlib 加密的使用
在python的时候 需要把 加密的数据转换成字节的形式 才能都进行加密
如果是 英文的 可以直接使用 b”nihao ’ 把字符串转换成 byte 类型的
如果是中文的 需要经过编码来进行解决 ‘你好’.encode(‘utf-8’)
import hashlibmd5 = hashlib.md5()md5.update('how to use md5 in python hashlib?'.encode('utf-8'))print(md5.hexdigest())
如果要加密的字节很长还可以, 分段进行加密操作, 例如:
import hashlibmd5 = hashlib.md5()md5.update('how to use md5 in '.encode('utf-8'))md5.update('python hashlib?'.encode('utf-8'))print(md5.hexdigest())MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。
sha1的使用
使用方法 和md5 是一样的 但是生成的是一个 40为的16进制的字符串来表示的
import hashlibsha1 = hashlib.sha1()sha1.update('how to use sha1 in '.encode('utf-8'))sha1.update('python hashlib?'.encode('utf-8'))print(sha1.hexdigest())
因为 md5 可能会被反推出来 , 存在一定的安全的隐患, 推荐的是使用 加密和 加盐的操作 来进行处理
就是在 进行加密的时候 加入一个字符串, 只要这个字符串不被外泄, 别人就很难破解你的密码
import hashlibmd5 = hashlib.md5()md5.update('how to use md5 in '.encode('utf-8'))md5.update('python hashlib?'.encode('utf-8'))print(md5.hexdigest())md5 = hashlib.md5()>>> def main(string):... md5.update((string + "hehe").encode("utf-8"))... print(md5.hexdigest())
itertools 模块的使用
Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数。
1. 无限次的重复
>>> import itertools>>> natuals = itertools.count(1)>>> for n in natuals:... print(n)...123...因为count()会创建一个无限的迭代器,所以上述代码会打印出自然数序列
- 无限次的重复
cycle()会把传入的一个序列无限重复下去:请注意 这里是一个序列
>>> import itertools>>> cs = itertools.cycle('ABC') # 注意字符串也是序列的一种>>> for c in cs:... print(c)...'A''B''C''A''B''C'...
- repeat()负责把一个元素无限重复下去,不过如果提供第二个参数就可以限定重复次数:
>>> ns = itertools.repeat('A', 3)>>> for n in ns:... print(n)...AAA
无限序列只有在for迭代时才会无限地迭代下去,如果只是创建了一个迭代对象,它不会事先把无限个元素生成出来,事实上也不可能在内存中创建无限多个元素。
无限序列虽然可以无限迭代下去,但是通常我们会通过takewhile()等函数根据条件判断来截取出一个有限的序列:
>>> natuals = itertools.count(1)>>> ns = itertools.takewhile(lambda x:x<=10, natuals)>>> list(ns)[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
chain()
chain()可以把一组迭代对象串联起来,形成一个更大的迭代器:
>>> for c in itertools.chain('ABC', 'XYZ'):... print(c)# 迭代效果:'A' 'B' 'C' 'X' 'Y' 'Z'
groupby()
groupby()把迭代器中相邻的重复元素挑出来放在一起:>>> for key, group in itertools.groupby('AAABBBCCAAA'):... print(key, list(group))...A ['A', 'A', 'A']B ['B', 'B', 'B']C ['C', 'C']A ['A', 'A', 'A']
实际上挑选规则是通过函数完成的,只要作用于函数的两个元素返回的值相等,这两个元素就被认为是在一组的,而函数返回值作为组的key。如果我们要忽略大小写分组,就可以让元素’A’和’a’都返回相同的key:
>>> for key, group in itertools.groupby('AaaBBbcCAAa', lambda c: c.upper()):... print(key, list(group))...A ['A', 'a', 'a']B ['B', 'B', 'b']C ['c', 'C']A ['A', 'A', 'a']
- python知识小结(2)
- python爬虫知识小结
- python知识小结1
- python知识小结
- python 知识小结(3)
- XML知识小结2
- 学习Python知识小结 杂记二
- 知识小结
- 知识小结
- python初学小结2
- python-numpy小结2
- Python知识总结2
- python知识2
- Struts核心知识部分小结(2)
- Java知识小结—(2)
- CSS知识小结CSS知识小结
- Bom 知识小结
- java知识小结
- 面试平安科技--二面
- 1037. 在霍格沃茨找零钱(20)
- Hadoop计算框架Mapreduce
- 从零开始的X栈工程师
- http状态码
- python知识小结(2)
- 1036. 跟奥巴马一起编程(15)
- 零基础学习R-加载数据包car报错
- Hadoop学习笔记(四)YARN
- PAT 1002. Business (35)
- 自己简单实现Spring的IOC原理
- python 知识小结(3)
- Lintcode149 Best Time to Buy and Sell Stock solution 题解
- maven中的scope属性