pydu:Python 常用数据结构和工具库,如何使用与贡献?

项目名称:
pydu

项目地址:
https://github.com/Prodesire/pydu

项目描述:
pydu ( python data structures and utils —— python 数据结构和工具)是一个面向 Python 2 和 3 的库。它收集自开源项目,也由贡献者创建。

示例代码:
英文版: http://pydu.readthedocs.io/en/latest/
中文版: http://pydu.readthedocs.io/zh/latest/

pydu 将平时常用的数据结构和工具都收录其中,可供日常开发使用,也可供学习借鉴。相比于 GitHub 上现存的 pyutils 等项目,其优势是积极维护,并有丰富文档。

现在,我们非常欢迎大家一起来提出想法、参与讨论、贡献代码,将平时常用的功能抽象为通用的工具集和数据结构,供大家学习或使用!
pydu:Python 常用数据结构和工具库,如何使用与贡献?


42 回复

支持


pydu是一个挺实用的Python第三方库,它把一些常用的数据结构和工具函数打包好了,用起来能省不少事儿。核心就两块:一是数据结构(比如BiDict双向字典、OrderedSet有序集合),二是各种工具函数(像文件操作、字符串处理这些)。

安装直接用pip:

pip install pydu

几个典型用法的代码示例:

  1. 双向字典(BiDict)
from pydu.dict import BiDict

bd = BiDict({'a': 1, 'b': 2})
print(bd['a'])  # 输出: 1
print(bd.inverse[1])  # 输出: 'a'  # 通过值反向查键
bd.inverse[2] = 'c'  # 修改值2对应的键为'c'
print(bd)  # 输出: {'a': 1, 'c': 2}
  1. 有序集合(OrderedSet)
from pydu.set import OrderedSet

os = OrderedSet([3, 1, 2, 1, 4])
print(list(os))  # 输出: [3, 1, 2, 4]  # 保持插入顺序且去重
os.add(0)
print(os.pop())  # 输出: 0  # 按LIFO顺序弹出
  1. 实用工具函数
from pydu import string, file

# 字符串操作
print(string.pluralize('book'))  # 输出: books
print(string.camel_to_underscore('HelloWorld'))  # 输出: hello_world

# 文件操作
file.write_lines('test.txt', ['line1', 'line2'])  # 写入文件
lines = file.read_lines('test.txt')  # 读取为列表
print(lines)

关于贡献: pydu的代码在GitHub上开源。如果你想加新功能或修bug,流程和大多数开源项目一样:先Fork仓库,在本地新建分支开发,写完测试,然后提Pull Request。重点是要保持代码风格一致(它用PEP 8),并且为新功能写好测试用例。提PR的时候把改动目的和测试情况说清楚就行。

总结:日常小工具用pydu挺方便,贡献代码注意看项目规范。

先 star 为敬

thanks

一起加油

不支持 win 7
$ pip install pydu
Collecting pydu
Using cached pydu-0.3.0.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File “<string>”, line 1, in <module>
File “C:\Users\ADMINI~1\AppData\Local\Temp\pip-build-4i3oi1nh\pydu\setup.p
y”, line 41, in <module>
long_description=open(‘README.rst’).read(),
UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xad in position 1162: ill
egal multibyte sequence

----------------------------------------
Command “python setup.py egg_info” failed with error code 1 in C:\Users\ADMINI~1
\AppData\Local\Temp\pip-build-4i3oi1nh\pydu\

支持一波,其实我觉得可以抛弃 python2 了

应该是 readme 中的中文引起的。请问是使用 Python2 还是 3 ?

主要是由于工作项目原因,还必须得支持 Python 2。 (逃

建议使用 Gitbook 维护,readthedocs.io 阅读体验略逊

https://github.com/Prodesire/pydu/blob/master/pydu/list.py

这个在 py3 里貌似就一句话

>>> list(dict.fromkeys(‘3938475638391’))
[‘3’, ‘9’, ‘8’, ‘4’, ‘7’, ‘5’, ‘6’, ‘1’]

Win 10, Python 3.6.3 安装失败。
pip install 错误信息和上面那位一样。
用本地文件安装同样失败:
[py36] PS E:\Download\pydu-master> python setup.py install
Traceback (most recent call last):
File “setup.py”, line 41, in <module>
long_description=open(‘README.rst’).read(),
UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xad in position 1162: illegal multibyte sequence

另外文档这里有三个 ipv6 写成 ipv4 了: https://pydu.readthedocs.io/zh/latest/network.html#pydu.network.is_ipv6


如果要保证元素出现次序稳定,应该用
>>> from collections import OrderedDict
>>> OrderedDict.fromkeys(‘3938475638391’).keys()

Network 里的 is_ipv6 部分没有改过来

python 3.6 以后的 dict 不会改变插入顺序了。

python2 的结果:

>>> list(dict.fromkeys(‘3938475638391’))
[‘1’, ‘3’, ‘5’, ‘4’, ‘7’, ‘6’, ‘9’, ‘8’]

.keys() 返回也不是 list 了。而是一个可以迭代的 view

https://www.python.org/dev/peps/pep-3106/

所以最后还是得 list() 一下。

支持一下,我用 smallcrocodile 提交了一个更新是关于 uniq list 的。
在概浏览了一下,总体上来说代码质量没有到能实用的程度。
比如 AttrDict

def getattr(self, key):
try:
return self[key]
except KeyError as k:
raise AttributeError(k)

这个异常处理明显有问题会抛出异常两次。
return self[key] 如果 key 不存在直接就会抛异常了,后面又人工抛一次,体验不太好。
还不如下面的方案,
value = self.get(key, KeyError(k))
if isinstance(value, KeyError):
raise AttributeError(k)

应该有更好的方案我只是举例说一下。
另外就是是不是考虑多层字典 AttrDict 嵌套的方案。

d = AttrDict(abc={‘a’: 1}, d=True)
d.abc.a 怎么样?

if isinstance(value, dict):
value = AttrDict(value)
return value

在 python2 里返回就是 list,python3 改成的 iterator
实际上造轮子是很难的,要解决众多版本特性差异问题。
官方说了不要把 3.6 的字典有序当成可以确保的事儿。
docs.python.org/3.6/whatsnew/3.6.html#new-dict-implementation
> The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon (this may change in the future, but it is desired to have this new dict implementation in the language for a few releases before changing the language spec to mandate order-preserving semantics for all current and future Python implementations; this also helps preserve backwards-compatibility with older versions of the language where random iteration order is still in effect, e.g. Python 3.5).

另外就是在 key 出现哈希碰撞和字典发生扩容后 key 顺序是会改变的。

先 star 为敬

官方的意思是,现在不能确保,因为将来才会变成强制标准。

但是 Raymond Hettinger 这种核心人物搞的东西,一般不会有人去动。

哈希碰撞和扩容发生顺序改变我倒是很感兴趣,有 case 么?

公司项目也在用 py2,支持

个人感觉 gitbook 体验也不太好。大家提提意见,看哪个更好?

关注点不太相同,pythonds 关注的是算法上的数据结构。pydu 关注的是实际业务领域(运维、web 等)方面的数据结构和工具集。

不错不错,纳入计划!

不能保证有序

今天尽快修复,感谢提出

这个方案是可行的,接下来我做个 benchmark,看现有的和这个方案哪个更快,占用更低

求 CPython 3.6 里的反例。

集思广益

这个是 AttriDict,概念上如果取值错误,应该抛出属性异常,所以才把 KeyError 改成 AttributeError

粗略看了下,不少功能在 py3 标准库里有实现😂

pydu.cmd.terminate→os.kill
pydu.console.console_size→shutil.get_terminal_size
pydu.exception.ignore→contextlib.suppress
pydu.misc.copy→shutil.copytree
pydu.network.dotted_netmask→ipaddress

当然 py2 用户不妨用楼主的实现,并且像 AttrDict 这种 JS 画风的语法糖官方肯定不会写的

这点赞同!

已修复在 Windows 上使用 Python 3 安装的问题,见 pydu 0.3.1 版本

3.6 中倒没有反例。如 所说,官方并不推荐这么做。

有一点你可能没有注意到,pydu 中的 uniq 还有一个参数是 key,举个例子:
class A(object):
def init(self, v):
self.v = v
def repr(self):
return ‘A({})’.format(self.v)

l = [A(2), A(1), A(2)]
uniq(l, key=lambda o: o.v) # 结果是 [A(2), A(1)]
list(dict.fromkeys(l)) # 结果是 [A(2), A(1), A(2)],原因大家都知道,列表中都是不同对象,我们需要对比的是 v,但是没办法做到

感谢斧正!
pydu.cmd.terminate→os.kill #terminiate 在 windows 上的处理调用了 Win32API,会更加靠谱
pydu.console.console_size→shutil.get_terminal_size #这个还真是
pydu.exception.ignore→contextlib.suppress #这个还真是,Py2 上倒是可以参考实现了
pydu.misc.copy→shutil.copytree #pydu 的 copy 更加上层,不用区分拷贝对象是文件还是文件夹,类似 Linux 上的 cp
pydu.network.dotted_netmask→ipaddress # 确实是这样,Python3 新增的 ipaddress 解决了相关问题,dotted_netmask 算是 py2 上的补充吧。这段代码更大的意义是学习背后的实现,来自 requests 库。


你那个算法上有个歧义的地方,set([1, 2, 1.0]) -> set([1,2])
用 dict.fromkeys 有相同的问题,因为 dict 的 key 都是调用的 objcet.hash()生成的,以前 python 就没有 set,都是用 dict 模拟。

可以的,作为脚手架的补充

我觉得类似 1 和 1.0 我们通常可以认为是一样的,那么不论是 set 还是 dic.fromkeys 的结果都可以接受。
如果说非要区分的话,倒是可以对 int, float, decimal.Decimal 做特殊处理。

回到顶部