python小知识3

  1. 在Unix/Linux下,可以使用fork()调用实现多进程。
    要实现跨平台的多进程,可以使用multiprocessing模块。
    进程间通信是通过Queue、Pipes等实现的。
  2. 多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享
  3. 获得锁的线程用完后一定要释放锁,否则那些苦苦等待锁的线程将永远等待下去,成为死线程。所以我们用try…finally来确保锁一定会被释放。

锁的好处就是确保了某段关键代码只能由一个线程从头到尾完整地执行,坏处当然也很多,首先是阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了。其次,由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁,导致多个线程全部挂起,既不能执行,也无法结束,只能靠操作系统强制终止。

  1. 多线程编程,模型复杂,容易发生冲突,必须用锁加以隔离,同时,又要小心死锁的发生。
    Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核。Python虽然不能利用多线程实现多核任务,但可以通过多进程实现多核任务。多个Python进程有各自独立的GIL锁,互不影响。
  2. ThreadLocal最常用的地方就是为每个线程绑定一个数据库连接,HTTP请求,用户身份信息等,这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源。
  3. Python的分布式进程接口简单,封装良好,适合需要把繁重任务分布到多台机器的环境下。
    注意Queue的作用是用来传递任务和接收结果,每个任务的描述数据量要尽量小。比如发送一个处理日志文件的任务,就不要发送几百兆的日志文件本身,而是发送日志文件存放的完整路径,由Worker进程再去共享的磁盘上读取文件。
  4. 注意Python的timestamp是一个浮点数。如果有小数位,小数位表示毫秒数。
  5. romtimestamp()转换是在timestamp和本地时间做转换。
  6. 很多时候,用户输入的日期和时间是字符串,要处理日期和时间,首先必须把str转换为datetime。转换方法是通过datetime.strptime()实现,需要一个日期和时间的格式化字符串:

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

  1. 把datetime往后或往前计算,得到新的datetime。加减可以直接用+和-运算符,不过需要导入timedelta这个类

  2. collections:namedtuple是一个函数,它用来创建一个自定义的tuple对象,并且规定了tuple元素的个数,并可以用属性而不是索引来引用tuple的某个元素。
    这样一来,我们用namedtuple可以很方便地定义一种数据类型,它具备tuple的不变性,又可以根据属性来引用,使用十分方便。

  3. collections:eque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈

  4. collections:使用dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict

  5. collections:OrderedDict的Key会按照插入的顺序排列,不是Key本身排序

  6. collections:ChainMap可以把一组dict串起来并组成一个逻辑上的dict。ChainMap本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找。

  7. Base64是一种任意二进制到文本字符串的编码方法,常用于在URL、Cookie、网页中传输少量二进制数据。

  8. import hmac
    message = b’Hello, world!’
    key = b’secret’
    h = hmac.new(key, message, digestmod=‘MD5’)
    #如果消息很长,可以多次调用h.update(msg)
    h.hexdigest()
    ‘fa4ee7d173f2d97ee79022d1a7355bcf’

可见使用hmac和普通hash算法非常类似。hmac输出的长度和原始哈希算法的长度一致。需要注意传入的key和message都是bytes类型,str类型需要首先编码为bytes。

  1. struct模块来解决bytes和其他二进制数据类型的转换。
  2. itertools提供的几个迭代器操作函数更加有用:

chain()
chain()可以把一组迭代对象串联起来,形成一个更大的迭代器
groupby()
groupby()把迭代器中相邻的重复元素挑出来放在一起

  1. itertools模块提供的全部是处理迭代功能的函数,它们的返回值不是list,而是Iterator,只有用for循环迭代的时候才真正计算。
  2. @contextmanager这个decorator接受一个generator,用yield语句把with … as var把变量输出出去,然后,with语句就可以正常地工作了
  3. 如果一个对象没有实现上下文,我们就不能把它用于with语句。这个时候,可以用closing()来把该对象变为上下文对象。例如,用with语句使用urlopen()
  4. 在Python中获取系统信息的另一个好办法是使用psutil这个第三方模块。顾名思义,psutil = process and system utilities,它不仅可以通过一两行代码实现系统监控,还可以跨平台使用,支持Linux/UNIX/OSX/Windows等,是系统管理员和运维小伙伴不可或缺的必备模块。
  5. 使用chardet检测编码非常容易,chardet支持检测中文、日文、韩文等多种语言。
  6. virtualenv为应用提供了隔离的Python运行环境,解决了不同应用间多版本的冲突问题。
  7. 用TCP协议进行Socket编程在Python中十分简单,对于客户端,要主动连接服务器的IP和指定端口,对于服务器,要首先监听指定端口,然后,对每一个新的连接,创建一个线程或进程来处理。通常,服务器程序会无限运行下去。
    同一个端口,被一个Socket绑定了以后,就不能被别的Socket绑定了。
  8. UDP的使用与TCP类似,但是不需要建立连接。此外,服务器绑定UDP端口和TCP端口互不冲突,也就是说,UDP的9999端口与TCP的9999端口可以各自绑定。
  9. ORM框架的作用就是把数据库表的一行记录与一个对象互相做自动转换。在Python中,最有名的ORM框架是SQLAlchemy
  10. Python对协程的支持是通过generator实现的。
  11. asyncio提供了完善的异步IO支持;
    异步操作需要在coroutine中通过yield from完成;
    多个coroutine可以封装成一组Task然后并发执行。
  12. Python从3.5版本开始为asyncio提供了async和await的新语法;
    注意新语法只能用在Python 3.5以及后续版本,如果使用3.4版本,则仍需使用上一节的方案。
  13. asyncio可以实现单线程并发IO操作。如果仅用在客户端,发挥的威力不大。如果把asyncio用在服务器端,例如Web服务器,由于HTTP连接就是IO操作,因此可以用单线程+coroutine实现多用户的高并发支持。
    asyncio实现了TCP、UDP、SSL等协议,aiohttp则是基于asyncio实现的HTTP框架。
发布了12 篇原创文章 · 获赞 0 · 访问量 511

猜你喜欢

转载自blog.csdn.net/s1421578048/article/details/103990443