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 pyaml
pip install ruamel.yaml

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

from ruamel import yaml
data={"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_longest

a = ["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 是_3
Person = 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 asyncio
import pyppeteer
from collections import namedtuple Response = 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.unique
class 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)

7 链式合并字典 chainmap 的使用

from collections import ChainMap

# ChainMap

d1 = {'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"] = 100
print(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 Counter

text = "abcdfegtehto;grgtgjri"  # 可迭代对象
lis = ["a", "c", "d", "t", "b"]
dic = {"a": 1, "b": 4, "c": 2, "d": 9} # 字典也可以
c = Counter() # 可以定义空容器然后 update
c.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)

Python 一些有趣的技巧,包括协程例的更多相关文章

  1. python自动化开发学习 进程, 线程, 协程

    python自动化开发学习 进程, 线程, 协程   前言 在过去单核CPU也可以执行多任务,操作系统轮流让各个任务交替执行,任务1执行0.01秒,切换任务2,任务2执行0.01秒,在切换到任务3,这 ...

  2. Python之线程、进程和协程

    python之线程.进程和协程 目录: 引言 一.线程 1.1 普通的多线程 1.2 自定义线程类 1.3 线程锁 1.3.1 未使用锁 1.3.2 普通锁Lock和RLock 1.3.3 信号量(S ...

  3. python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用

    python爬虫---单线程+多任务的异步协程,selenium爬虫模块的使用 一丶单线程+多任务的异步协程 特殊函数 # 如果一个函数的定义被async修饰后,则该函数就是一个特殊的函数 async ...

  4. python day 20: 线程池与协程,多进程TCP服务器

    目录 python day 20: 线程池与协程 2. 线程 3. 进程 4. 协程:gevent模块,又叫微线程 5. 扩展 6. 自定义线程池 7. 实现多进程TCP服务器 8. 实现多线程TCP ...

  5. python之并发编程(线程\进程\协程)

    一.进程和线程 1.进程 假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时CPU只能静静地等待任务A读取完数据才能继续执行,这样就白白浪费了CPU资源.是 ...

  6. Py修行路 python基础 (十二) 协程函数应用 列表生成式 生成器表达式

    一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._next_() 取下一个值 优点: 1.提供了 ...

  7. Python之进程、线程、协程

    进程和线程的目的 进程和线程目的是为了:提高执行效率 现代操作系统比如Mac OS X,UNIX,Linux,Windows等,都是支持“多任务”的操作系统. 什么叫“多任务“呢?简单地说,就是操作系 ...

  8. Python菜鸟之路:Python基础-线程、进程、协程

    上节内容,简单的介绍了线程和进程,并且介绍了Python中的GIL机制.本节详细介绍线程.进程以及协程的概念及实现. 线程 基本使用 方法1: 创建一个threading.Thread对象,在它的初始 ...

  9. python中进程、线程、协程简述

    进程 python中使用multiprocessing模块对进程进行操作管理 进程同步(锁.信号量.事件) 锁 —— multiprocessing.Lock 只要用到了锁 锁之间的代码就会变成同步的 ...

随机推荐

  1. 分词、词性标注POS等学习【转载】

    转自:https://cloud.tencent.com/developer/article/1091815 1. 分词(Word Cut) 英文:单词组成句子,单词之间由空格隔开 中文:字.词.句. ...

  2. vue使用md5加密

    import crypto from 'crypto' export default { name: 'HelloWorld', data () { return { msg: 'Welcome to ...

  3. selenium + python 测试环境搭建 (WINDOWS)

    1. 下载Python , 运行.exe -> http://python.org/getit/ 2. 下载Python Setuptools 基础包管理工具安装,官方文档参考 https:// ...

  4. leetcode473 Matchsticks to Square

    一开始想求所有结果为target的组合来着,但是所选元素不能重叠.用这个递归思想很简单,分成四个桶,每次把元素放在任意一个桶里面,最后如果四个桶相等就可以放进去,有一个地方可以剪枝,假如任意一个桶的元 ...

  5. Cocos Code IDE (下载地址)

    Cocos Code IDE 1.2.0 下载地址       Cocos Code IDE 1.2.0 Win32 下载地址: http://www.cocos2d-x.org/filedown/c ...

  6. Linux基础(二)centOS7密码重置

    之前安装linux的时候,为了安全起见,起了一个非常特别的,长的密码.然后,就不记得了密码. 下面通过进入单用户模式,就行挽救. 1>重启系统,在系统菜单选择页按 [上下方向键],使界面停在该界 ...

  7. nginx: [error] invalid PID number "" in "/usr/local/webserver/nginx/logs/nginx.pid" (原)

    进入nginx文件下,例如 :/usr/local/nginx/sbin [root@iZ25f7emo7cZ /]# cd /usr/local/nginx/sbin 运行命令: [root@iZ2 ...

  8. Ecshop表结构 order_info

    CREATE TABLE IF NOT EXISTS `ecs_order_info` (  `order_id` mediumint(8) unsigned NOT NULL AUTO_INCREM ...

  9. ProxySQL(读写分离)部署

    proxySQL是MySQL的中间件产品,是灵活强大的代理层,实现读写分离,支持Query路由功能,支持动态指定某个SQL进行缓存,支持动态加载配置,故障切换和一些SQL 过滤功能 环境: 192.1 ...

  10. rpm方式安装MySQL5.1.73

    1.安装MySQL server 首先下载好mysql的rpm安装包 使用rpm命令安装: rpm -ivh MySQL-server-5.1.73-1.glibc23.i386.rpm 命令解释:i ...