Python使用小技巧
1,查询U盘剩余空间大小
st = os.statvfs('/media/usb0/') free = (st.f_bavail*st.f_frsize)/1024/1024 # 单位是M
2,查询U盘或者某个目录/文件大小
size = os.path.getsize('/media/usb0/mega.log') # 单位是字节
3,把日志文件导出到U盘
try: p = pexpect.spawn('lsblk') index = p.expect([UDISK, pexpect.EOF, pexpect.TIMEOUT]) if index != 0: print('没有U盘') return st = os.statvfs(UDISK) if (st.f_bavail * st.f_frsize) < UDISK_MIN: print('U盘空间不足') return os.system('sudo cp mega.log* ' + UDISK) os.system('sync') except Exception as e: print(e) print('导出失败')
4,把不可打印的字符过滤掉
tt = ''.join(filter(lambda x: x in string.printable, tt))
5,遍历符合条件的文件,并加入列表
import os list= [] files = os.listdir(r'../raspberry') for file in files: if file.endswith('.py'): list.append(file) print(list)
6,在树莓派后台检查树莓派上插的U盘的文件大小
du -s /media/usb0/mega.log --apparent-size
7,查询window磁盘占用率:
from subprocess import PIPE,Popen proc = Popen( 'fsutil volume diskfree E:', stdin=None, stdout=PIPE, stderr=PIPE, shell=True) outinfo,erronfo = proc.communicate() outinfo = outinfo.decode('gbk') outputlist = outinfo.splitlines() free = int(outputlist[0].split(':')[1].strip()) total = int(outputlist[1].split(':')[1].strip())
8,使用python执行指令后有返回内容,
os.system也可以执行指令,但是,不会有返回内容
def adbdevices(deviceid): try: p = wexpect.spawn('adb devices') p.expect(deviceid, timeout=5) #判断返回值是否包含关键字 deviceid except: return 1 return 0
9,有多个返回值
def get_best_trip_by_user_id(user_id): return { 'user': get_user(user_id), 'trip': get_best_trip(user_id) }
10,all() any()z在条件判断中使用
all(seq)
:仅当seq
中所有对象都为布尔真时返回True
,否则返回False
any(seq)
:只要seq
中任何一个对象为布尔真就返回True
,否则返回False
#仅当序列中所有数字大于 10 时,返回 True def all_numbers_gt_10_2(numbers): return bool(numbers) and all(n > 10 for n in numbers)
等价于下面这段代码,但是比下面的代码简洁
def all_numbers_gt_10(numbers): """仅当序列中所有数字大于 10 时,返回 True """ if not numbers: return False for n in numbers: if n <= 10: return False return True
11, try/while/for 中 else 分支
先看看这个函数:
def do_stuff(): first_thing_successed = False try: do_the_first_thing() first_thing_successed = True except Exception as e: print("Error while calling do_some_thing") return # 仅当 first_thing 成功完成时,做第二件事 if first_thing_successed: return do_the_second_thing()
在函数 do_stuff
中,我们希望只有当 do_the_first_thing()
成功调用后*(也就是不抛出任何异常)*,才继续做第二个函数调用。为了做到这一点,我们需要定义一个额外的变量 first_thing_successed
来作为标记。
其实,我们可以用更简单的方法达到同样的效果:
def do_stuff(): try: do_the_first_thing() except Exception as e: print("Error while calling do_some_thing") return else: return do_the_second_thing()
在 try
语句块最后追加上 else
分支后,分支下的do_the_second_thing()
便只会在 try 下面的所有语句正常执行(也就是没有异常,没有 return、break 等)完成后执行。
类似的,Python 里的 for/while
循环也支持添加 else
分支,它们表示:当循环使用的迭代对象被正常耗尽、或 while 循环使用的条件变量变为 False 后才执行 else 分支下的代码。
12,你要判断某个变量是否为 None 时,请使用 is
而不是 ==
13,and
运算符的优先级大于 or
>>> (True or False) and False >>> True or False and False
它们的值分别是 False
和 True
14,统计list里各个字符串的个数
l = ['4', '5', '6', '5', '6', '8', '9', '8', '6', '5', '7', '5', '4', '6'] def ff(): dict = {} for key in l: # if int(key) % 2 == 0: dict[key] = dict.get(key, 0) + 1 return dict print('ff = ', ff())
ff = {'4': 2, '5': 4, '6': 4, '8': 2, '9': 1, '7': 1}
15,脱敏效果
# coding: utf-8 import re class CyclicMosaic: _chars = ['*', 'x'] def __init__(self): self._char_index = 0 def generte(self, matchobj): char = self._chars[self._char_index] self._char_index = (self._char_index+1)%len(self._chars) # 1 % 2 lenth = len(matchobj.group()) return lenth * char s = '商店里有120个苹果,小明以12元的价格买走了9个' print(re.sub(r'\d+', CyclicMosaic().generte, s)) # 商店里有***个苹果,小明以xx元的价格买走了*个 def mosaic_matchobj(matchobj): lenth = len(matchobj.group()) return '*' * lenth print(re.sub(r'\d+', mosaic_matchobj , s)) # 商店里有***个苹果,小明以**元的价格买走了*个
16, 装饰器
import time def display_time(func): def wrapper(*args): t1 = time.time() result = func(*args) t2 = time.time() # print('Total time: {:.4} s'.format(t2 - t1)) print(f'Total time: {t2-t1:.4} s') return result return wrapper def is_prime(num): if num < 2: return False elif num == 2: return True else: for i in range(2, num): if num % i == 0: return False return True @display_time def prime_nums(maxnum): count = 0 for i in range(2, maxnum): if is_prime(i): # print(i) count += 1 return count count = prime_nums(10000) print(count)
运行结果:
Total time: 0.1937 s 1229
17, bisect.bisect 用在有序序列的排名中
import bisect def rank(score): breakpoints = (6, 7, 8, 8.5) grade = ('D', 'C', 'B', 'A', 'S') index = bisect.bisect(breakpoints, float(score)) return grade[index] print(rank(5.3)) # D print(rank(8.3)) # A
18 生成器提升性能
# coding:utf-8 # 去过普吉岛的人员数据 users_visited_phuket = [ {"first_name": "Sirena", "last_name": "Gross", "phone_number": "650-568-0388", "date_visited": "2018-03-14"}, {"first_name": "James", "last_name": "Ashcraft", "phone_number": "412-334-4380", "date_visited": "2014-09-16"}, ] # 去过新西兰的人员数据 users_visited_nz = [ {"first_name": "Justin", "last_name": "Malcom", "phone_number": "267-282-1964", "date_visited": "2011-03-13"}, {"first_name": "Albert", "last_name": "Potter", "phone_number": "702-249-3714", "date_visited": "2013-09-11"}, ] def find_potential_customers_v2(): """找到去过普吉岛但是没去过新西兰的人,性能改进版 """ # 首先,遍历所有新西兰访问记录,创建查找索引 nz_records_idx = { (rec['first_name'], rec['last_name'], rec['phone_number']) for rec in users_visited_nz } for rec in users_visited_phuket: key = (rec['first_name'], rec['last_name'], rec['phone_number']) if key not in nz_records_idx: yield rec
19,统计dict元素个数的几种方式
# (LBYL)风格 Look Before You Leap
def counter_ap(l): """计算列表里面每个元素出现的数量""" result = {} for key in l: # 主流程:累加计数器 if key in result: result[key] += 1 # **边界情况:当元素第一次出现时,先初始化值为 1** else: result[key] = 1 return result # 执行结果: print(counter_ap(['apple', 'banana', 'apple'])) {'apple': 2, 'banana': 1}
# 获取原谅比许可简单(EAFP) def counter_af(l): result = {} for key in l: try: # 总是直接执行主流程:累加计数器 result[key] += 1 except KeyError: # 边界情况:当元素第一次出现时会报错 KeyError,此时进行初始化 result[key] = 1 return result
# 使用 defaultdict from collections import defaultdict def counter_by_collections(l): result = defaultdict(int) for key in l: result[key] += 1 return result
20, 提取字符串中的数字,并且转换成整型
name = 'RELAYOPENS_5_6_11_12' pin = name.split('_')[1:] a = list(map(int, pin)) print(a) # [5, 6, 11, 12]
21