前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 标准库 pwd 背后的秘密

Python 标准库 pwd 背后的秘密

作者头像
初代庄主
发布2021-12-20 13:42:00
1.5K1
发布2021-12-20 13:42:00
举报
文章被收录于专栏:初代庄主
一周一个标准库之 PWD

背景

用 Python 讨生活这么多年,我一直以来的一个观点就是 “在 Python 这个大环境下 import xxx 写完之后功能就实现了 50% ~ 80% 。”。

Python 的编码效率高主要原因在于一些通用的功能模块、算法、数据结构 ,前人已经做好了。我拿过来用就行了,经验上来看绝大多数问题都有对应的模块。所以后面 Python 这个系列打算把标准库和常用的第三方库讲一讲(又可以水两年)。作为标准库的第一篇我决定对 pwd 这个模块下手。

PWD 要解决的问题

这个库的目标简单到要死,一方面用于检查给定的用户是否存在,另一方面可用于用户读取用户的 uid,gid 等信息,总之就是读操作。

如果我们选择自己硬写的话,pwd 的功能也不是不可替代;但相比复用标准库我们的代码可能要长好多。下面写一个检查给定用户是否存在的功能。

代码语言:javascript
复制
#!/usr/bin/env python3

def has_user(name:str="root"):
    """
    检查给定的用户在当前操作系统中是否存在

    Parameter
    ---------
    name: str
        用户名

    Return
    ------
    bool
    """
    # 参数处理(用户名后面是一个:号的,在这里加一个:可以把正则省略)
    name = name.strip()+":"
    if name == ":":
        return False

    # 检查操作系统上有没有这个用户
    with open("/etc/passwd") as pwd_file_obj:
        for line in pwd_file_obj:
            if line.startswith(name):
                return True

    return False



if __name__ == "__main__":
    users = ['root','mysql','notexistsuser']
    for user in users:
        print(f"{user} exists == {has_user(user)}")

    # 测试一种异常的情况
    user = "roo"
    print(f"{user} exists == {has_user(user)}")

运行的效果

代码语言:javascript
复制
python3 main.py 

root exists == True
mysql exists == False
notexistsuser exists == False
roo exists == False

检查一个用户是否存在都要这么多行代码,这并不 Pythonic 呀! 能不能 import 就完成 50%?

PWD 写法

标准库用的好效率低不了,先来看一下用 pwd 这个标准库模块,我们的代码要怎么重写。

代码语言:javascript
复制
#!/usr/bin/env python3

import pwd

def has_user(name:str="root"):
    """
    检查给定的用户在当前操作系统中是否存在

    Parameter
    ---------
    name: str
        用户名

    Return
    ------
    bool
    """
    try:
        return pwd.getpwnam(name) != None
    except KeyError as err:
        return False

if __name__ == "__main__":
    users = ['root','mysql','notexistsuser']
    for user in users:
        print(f"{user} exists == {has_user(user)}")

    # 测试一种异常的情况
    user = "roo"
    print(f"{user} exists == {has_user(user)}")

运行效果

代码语言:javascript
复制
python3 pwd-v1.py 

root exists == True
mysql exists == False
notexistsuser exists == False
roo exists == False

PWD 自身有什么问题

其实对于 pwd 这个模块评价我也是经过好多年才做到一个客观 & 理性的。

1、一开始我认为它的问题就在于 API 接口命名不友好,本来一个好好的 get_pw_by_name 它硬给搞成了 getpwnam ,少写几个字母会这么爽吗?

2、后来因为一些工作上的原因(我们这边希望 MySQL DBA 要有 Debug MySQL 的能力),就这样我又把 C/C++ 从故纸堆里捡了回来,遥想当年就是看到下面这样一段 C 代码的时候顿悟的 pwd 模块。

代码语言:javascript
复制
#include<pwd.h>
#include<stdio.h>

int main() {
    struct passwd *user;
    user = getpwnam("root");
    printf("%s \n",user->pw_name);
    return 0;
}

运行效果

代码语言:javascript
复制
gcc use-pwd.c -o use-pwd && ./use-pwd
root

3、现在我觉得 pwd 库没有毛病,它忠实的“包装”了 C 库,做到了对 C 语言程序员友好;并且这种实例方式也比原生的 Python 实现在性能上要好。

最后

pwd 还有一个兄弟模块叫 grp ,实现上和 pwd 是一样的。想到如果我下周用 grp 再水一篇,一来我会不好意思,二来也无聊,还不如聊宏观经济,吹吹水来的开心,所以这周更新两个模块。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 初代庄主 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档