几个python冷门却实用的小技巧

1、如何在运行状态下查看源代码?

一般我们会用IDE来帮助我们完成这项工作,比如 Ctrl + 鼠标点击 就可以进入函数的源代码,但是如果没有IDE呢?
用 inspect 模块。

In [1]: import inspect

In [2]: def show(x,y):
   ...:     print(x^2+y^2)
   ...:

In [3]: print(inspect.getsource(show))
   ...:
#下面为print的输出
def show(x,y):
    print(x^2+y^2)

2、如何将嵌套for循环写成单行?

我们通常会写如下的嵌套for循环。

list1=range(1,3)
list2=range(3,6)
list3=range(7,9)
for i in list1:
	for j in list2:
		for k in list3:
			print(i+j+k)

可以发现,这样的代码不美观,可读性差,改用 itertools库。

In [5]: from itertools  import product

In [6]: list1=range(1,3)
   ...: list2=range(3,6)
   ...: list3=range(7,9)

In [7]: for i,j,k in product(list1,list2,list3):
   ...:     print(i+j+k)

3、如果选择print函数来进行调试,那么如何用print输出日志?

注意!!!在python3中,print是一个函数!!!它可以接受很多额外的参数,而且具有函数共性的性质。(具体的请自行百度或者以后的博文里会出现)

with open('rizhi.log',mode='w') as f:
	print('hello',file=f,flush=True)

3、如果快速计算函数运行时间?

常用方式:

import time

start = time.time()

#function

end = time.time()
print(end-start)

改进版:使用 timeit

In [1]: def add(x,y):
   ...:     print(x+y)
   ...:

In [2]: import timeit

In [3]: print(timeit.timeit(lambda : add(1,2),number=1)) #这里必须用lambda匿名函数的形式,
#然后number是指定函数运行次数,也是必不可少的参数。
#下面为输出
3
0.0007528200000024299

4、如果利用自带的缓存机制提高效率?

缓存机制是一种很重要的机制,它可以帮助我们记住之前代码所做过的一些操作,当后面的代码中出现一样的操作时,就可以直接调用之前的结果,而不用重复去计算。
举一个最简单的例子,利用递归计算斐波那契数列。1,1,2,3,5,8,13…
在递归计算时,计算f(5)需要计算f(3)和f(4),而计算f(4)又需要去计算f(3)和f(2),可见,这里f(3)重复了,如果没有缓存机制,那么需要计算两次f(3),如果有缓存机制,那么只需要计算一次f(3)即可。之前有过编程基础的小伙伴也许知道,用递归计算斐波那契数列的一个优化方法就是用一个动态数组储存每一步计算出来的 f 。
python3.2及以上版本为我们提供了缓存机制,这个机制实现于 functool 模块中的 lru_cache 装饰器。

@functools.lru_cache(maxsize=None, typed=False)

参数解释:
maxsize:最多可以缓存多少个此函数的调用结果,如果为None,则无限制,设置为 2 的幂时,性能最佳
typed:若为 True,则不同参数类型的调用将分别缓存。

举个例子:

from functools import lru_cache

@lru_cache(None)
def add(x, y):
    print("calculating: %s + %s" % (x, y))
    return x + y

print(add(1, 2))
print(add(1, 2))
print(add(2, 3))

输出如下:
calculating: 1 + 2
3
3
calculating: 2 + 3
5

再举个斐波那契的例子:

import timeit
def jisuan(n):
	if n<2:
		return n
	return jisuan(n-1)+jisuan(n-2)
print(timeit.timeit(lambda :jisuan(30),number=1))

结果是0.32秒
下面用缓存机制

from functools import lru_cache

@lru_cache(None)
def jisuan(n):
	if n<2:
		return n
	return jisuan(n-1)+jisuan(n-2)

print(timeit.timeit(lambda :jisuan(30), number=1))

结果是2.6*1e-5 秒,可见快了4个数量级!

5、如果读取超大文件?比如超过10G的文件?

一般而言的文件操作,一次性读取。

with open("file.txt", "r") as fp:
    data = fp.read()

一个多行的超大文件可以逐行读取

def read_from_file(filename):
    with open(filename, "r") as fp:
        yield fp.readline()

但是如果该超大文件只有一行呢?
我们需要为read函数设置参数,使它一次只读取我们设置的字节大小的数据。

def read_from_file(filename, block_size = 1024 * 8):
    with open(filename, "r") as fp:
        while True:
            chunk = fp.read(block_size)
            if not chunk:
                break

            yield chunk

一次只读取8kb。

参考文献及说明:

本博客参考公众号“简说python”的文章“5年 Python 功力,总结了 10 个开发技巧”,链接如下:
https://mp.weixin.qq.com/s/NKnlX0LmwVjfDYSjdNx_VA
如若侵权,请联系删除。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值