博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python 一些有趣的技巧,包括协程例
阅读量:5038 次
发布时间:2019-06-12

本文共 7491 字,大约阅读时间需要 24 分钟。

1. 路径操作

比起 os 模块的 path 方法,python3 标准库的 pathlib 模块的 Path 处理起路径更加的容易。 ####获取当前文件路径 前提导入 os 和 pathlib 包。。 os 版:

print(os.path.dirname(__file__))    print(os.getcwd())

pathlib 版:

print(pathlib.Path.cwd())

看着好像没啥区别,然后看下面这个。

获取上两级文件目录

os 版

print(os.path.dirname(os.path.dirname(os.getcwd())))

pathlib 版

print(pathlib.Path.cwd().parent.parent)

拼接路径

os 版

print(os.path.join(os.path.dirname(os.path.dirname(os.getcwd())),"yamls","a.yaml"))

pathlib 版

parts=["yamls","a.yaml"] print(pathlib.Path.cwd().parent.parent.joinpath(*parts))

运行时拼接路径

os 版

os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'yamls',f'{site_name}.yaml')

pathlib 版

parts=["yamls","a.yaml"]print(pathlib.Path(__file__).resolve().parent.parent.joinpath(*parts))

另外 pathlib 生成的是个对象<class 'pathlib.PosixPath'>,在 open 文件操作中可以直接运行的但是如果当作字符串操作会出现错误,此时需要对其进行转换,使用 os.fspath()即可,不过一般很少有操作路径字符串的习惯。 综合起来,还是 pathlib 拼接路径方便。

 

2. 保存标准格式的 yaml 文件

编程免不了要写配置文件,怎么写配置也是一门学问。 YAML 是专门用来写配置文件的语言,非常简洁和强大,远比 JSON 格式方便。 YAML 在 python 语言中有 PyYAML 安装包。 前提安装第三方库

pip install pyamlpip install ruamel.yaml

关于 yaml 的读取知识网上一堆了我就不说了,这里主要说写入。

from ruamel import yamldata={
"age":23,"sex":"男","name":"牛皮"} with open(conf_file, "w", encoding='utf-8') as fs: yaml.dump(data, fs, Dumper=yaml.RoundTripDumper, allow_unicode=True)

yaml 写文件和 json 一样也是使用 dump。

 

3. 同时迭代两个列表

以前的时候我是这么解决的

a = ["a", "b", "c", "d"]b = [1, 2, 3] # 空的补充 None for index, a_item in enumerate(a): b_item = None if len(b) - 1 <= index: pass else: b_item = b[index] print({a_item:b_item})

现在我通过 itertools 标准库的 zip 升级版 zip_longest 解决,可以通过 fillvalue 参数补充缺失值。当然如果比较的元素个数相同可以直接用 zip。

from itertools import zip_longesta = ["a", "b", "c", "d","e"] b = [1, 2, 3] # 空的补充 None for a_item, b_item in zip_longest(a,b,fillvalue=0): print({a_item:b_item})

4. 三元表达式还能这么用?

一般的我们这样写

a="hello" if 2>1 else "bye"print(a)

我们知道 python 中 false 实际式 0,true 是 1,所以对于上面的式子我们就可以这么写了。

a=["hello","bye"][2<1]print(a)

因为 2<1 是 false 也就是 0,所以输出了第一个元素 hello。

 

5.简单的类使用 namedtuple 代替

先来一个简单的例子

import collections# Person=collections.namedtuple('Person','name age')# 如果使用 python 中的关键字会出现错误,此时使用 rename 字段。# 按照元素在元组中的下标赋值。class 就是_2,def 是_3Person = collections.namedtuple('Person', ['name', 'age', 'class', 'def', 'name', 'name'], rename=True) p = Person(name='lisa', age='12', _2="class2", _3="def", _4="name2", _5="name3") print(p) # 如果出现相同的字段第二次出现的时候也是用其下标,参考上面的例子。 # _fields 查看字段名,可以发现内置模块和重复的字段标记为_加下标的形式 print(p._fields) # 使用_asdict 将 namedtuple 转为 OrderedDict。 od = p._asdict() print(od) # 然后可以转为字典 print(dict(od)) # _replace()方法构建一个新实例,因为 namedtuple 是不可变类型所以这个方法可以返回一个新的对象。 new_p = p._replace(name="samJ") print(new_p) print(new_p is p) # 可以看到不是同一个对象。

一个实用的例子 pyppeteer 的例子感受下

import asyncioimport pyppeteerfrom collections import namedtupleResponse = namedtuple("rs", "title url html cookies headers history status") async def get_html(url, timeout=30): # 默认 30s browser = await pyppeteer.launch(headless=True, args=['--no-sandbox']) page = await browser.newPage() res = await page.goto(url, options={ 'timeout': int(timeout * 1000)}) data = await page.content() title = await page.title() resp_cookies = await page.cookies() resp_headers = res.headers resp_history = None resp_status = res.status response = Response(title=title, url=url, html=data, cookies=resp_cookies, headers=resp_headers, history=resp_history, status=resp_status) return response if __name__ == '__main__': url_list = ["http://www.10086.cn/index/tj/index_220_220.html", "http://www.10010.com/net5/011/", "http://python.jobbole.com/87541/"] task = (get_html(url) for url in url_list) loop = asyncio.get_event_loop() results = loop.run_until_complete(asyncio.gather(*task)) for res in results: print(res.title)

6 使用枚举让数字变得更易懂。

import enum# 枚举@enum.uniqueclass Sex(enum.Enum):    man = 12    woman = 13    # 因为加了唯一值的装饰器所以下面添加属性会报错    # boy=12print(Sex.man.name)print(Sex.woman.value)# 遍历for item in Sex:    print(item.name)    print(item.value)print("-" * 40)# 其他使用方式words = enum.Enum(    value='item',    names=('a b c d e f'),)# 输出元素 c,必须是上面 names 里含有的值print(words.c)print(words.f)# 因为 names 不含有 w 所以报错try:    print(words.w)except AttributeError as e:    print(e.args)print("-" * 40)for word in words:    print(word.name, word.value)  # 默认赋值为、从 1 开始自增。print("-" * 40)# 如果自定义元素的值啧改为一下元组的形式words2 = enum.Enum(    value='item2',    names=[('a', 23), ('b', 56), ("c", 12), ("d", 333)])for word2 in words2:    print(word2.name, word2.value)

7 链式合并字典 chainmap 的使用

 

from collections import ChainMap# ChainMapd1 = {
'a': 1, 'b': 2}d2 = {
'a2': 3, 'b2': 4}d3 = {
'a3': 5, 'b3': 6}d4 = {
'a4': 7, 'b4': 8}c = ChainMap(d1, d2, d3, d4) # 多个字典合并为一个for k, v in c.items(): print(k, v)print(c.maps) # 要搜索的索引列表c.maps = list(reversed(c.maps)) # 逆转映射列表print(c)# 因为 c 和 d1-d4 对应的索引位置实际是一个所以,修改 c 的时候会影响到 d1 到 d4 其中饿的一个值,同理修改# d1-d4 的时候也会影响到 c。# 所以使用 new_child 创建一个新的映射。再修改就影响不到底层的数据了。c2 = c.new_child()c2["a4"] = 100print(c)print(c2)# 输出发现 c 的值没有发生变化,只要 c2 变化。d5 = {
"a5": 34, "b5": 78}c2 = c2.new_child(d5) # 可以在原来的映射基础上添加新的映射print(c2)

8 在不打乱列表顺序的基础上插入元素

import bisect"""bisect 模块,用于维护有序列表。bisect 模块实现了一个算法用于插入元素到有序列表。在一些情况下,这比反复排序列表或构造一个大的列表再排序的效率更高。Bisect 是二分法的意思,这里使用二分法来排序,它会将一个元素插入到一个有序列表的合适位置,这使得不需要每次调用 sort 的方式维护有序列表。"""values = [14, 85, 77, 26, 50, 45, 66, 79, 10, 3, 84, 77, 1]print("New Pos Content")print("--- --- -------")l = []for i in values:    postion = bisect.bisect(l, i)  # 返回插入的位置    bisect.insort(l, i)  # 等于 insort_right    print('{:3}{:3}'.format(i, postion), l)"""Bisect 模块提供的函数有:bisect.bisect_left(a,x, lo=0, hi=len(a)) :查找在有序列表 a 中插入 x 的 index。lo 和 hi 用于指定列表的区间,默认是使用整个列表。如果 x 已经存在,在其左边插入。返回值为 index。bisect.bisect_right(a,x, lo=0, hi=len(a))bisect.bisect(a, x,lo=0, hi=len(a)) :这 2 个函数和 bisect_left 类似,但如果 x 已经存在,在其右边插入。bisect.insort_left(a,x, lo=0, hi=len(a)) :在有序列表 a 中插入 x。和 a.insert(bisect.bisect_left(a,x, lo, hi), x) 的效果相同。bisect.insort_right(a,x, lo=0, hi=len(a))bisect.insort(a, x,lo=0, hi=len(a)) :和 insort_left 类似,但如果 x 已经存在,在其右边插入。Bisect 模块提供的函数可以分两类:bisect* 只用于查找 index, 不进行实际的插入;而 insort* 则用于实际插入。该模块比较典型的应用是计算分数等级:"""

8 关于字典的逻辑运算你了解多少

 

# 使用&操作符查看字典的相同之处#字典键支持常见的集合操作,并集交集差集。a = {
'x': 1, 'y': 2, 'z': 3}b = {
'w': 2, 'z': 4, 'x': 3, 'z': 3}# 获取相同的键c = a.keys() & b.keys()print(c)# 获取相同的键值对d = a.items() & b.items()print(d)# 创建一个新的字典并删除某些键e = {k: a[k] for k in a.keys() - {
'z', 'x'}}print(e)

9 给切片起个名字

a="safr3.14"print(a[-4:])#上面可以改为pie=slice(len(a)-4,len(a))print(a)

10 获取出现频率高的元素

from collections import Countertext = "abcdfegtehto;grgtgjri"  # 可迭代对象lis = ["a", "c", "d", "t", "b"]dic = {
"a": 1, "b": 4, "c": 2, "d": 9} # 字典也可以c = Counter() # 可以定义空容器然后 updatec.update(text)c2 = Counter()c2.update(dic)c3 = Counter(lis) # 也可以直接传入对象print(c)print(c2)print(c3)# 使用 c.most_comman(n)获取前 n 出现频率最高的元素,列表元组类型print(c.most_common(4))

import enum # 枚举@enum.uniqueclass Sex(enum.Enum): man = 12 woman = 13# 因为加了唯一值的装饰器所以下面添加属性会报错# boy=12 print(Sex.man.name) print(Sex.woman.value) # 遍历for item in Sex: print(item.name) print(item.value) print("-" * 40) # 其他使用方式 words = enum.Enum( value='item', names=('a b c d e f'), ) # 输出元素 c,必须是上面 names 里含有的值 print(words.c) print(words.f) # 因为 names 不含有 w 所以报错try: print(words.w) except AttributeError as e: print(e.args) print("-" * 40) for word in words: print(word.name, word.value) # 默认赋值为、从 1 开始自增。 print("-" * 40) # 如果自定义元素的值啧改为一下元组的形式 words2 = enum.Enum( value='item2', names=[('a', 23), ('b', 56), ("c", 12), ("d", 333)] ) for word2 in words2: print(word2.name, word2.value)

转载于:https://www.cnblogs.com/pythonClub/p/10022432.html

你可能感兴趣的文章
HDU 1011 Starship Troopers (树形DP)
查看>>
手把手教你写DI_1_DI框架有什么?
查看>>
.net常见的一些面试题
查看>>
OGRE 源码编译方法
查看>>
上周热点回顾(10.20-10.26)
查看>>
C#正则表达式引发的CPU跑高问题以及解决方法
查看>>
云计算之路-阿里云上:“黑色30秒”走了,“黑色1秒”来了,真相也许大白了...
查看>>
APScheduler调度器
查看>>
设计模式——原型模式
查看>>
【jQuery UI 1.8 The User Interface Library for jQuery】.学习笔记.1.CSS框架和其他功能
查看>>
如何一个pdf文件拆分为若干个pdf文件
查看>>
web.xml中listener、 filter、servlet 加载顺序及其详解
查看>>
前端chrome浏览器调试总结
查看>>
获取手机验证码修改
查看>>
数据库连接
查看>>
python中数据的变量和字符串的常用使用方法
查看>>
等价类划分进阶篇
查看>>
delphi.指针.PChar
查看>>
Objective - C基础: 第四天 - 10.SEL类型的基本认识
查看>>
java 字符串转json,json转对象等等...
查看>>