心路历程

  之前学linux,虽然学的行算不错,不过总感觉差了点什么,自己找不到也说不出来;直到有一天我看到别人mount上了一个普通文件;

  当时给我的感觉这太不可思议了,这个文件又不是块设备;后来脑子里突然想到一句话“一切些文件”,一身的冷汉;原来这个就是linx

  的哲学它不是一句口号!它是linux这门武功的上乘心法。 linux我顿悟了。

  昨天夜里看python看到一句话“python语言最好的品质之一是一致性”;这种高度的一致性来自于哪里?我想应该是针对某一特定的

  问题在python中“最优解只有一个”的原因。

从赋值语句看语言的一致性:

  赋值语句每一门语言都有不过python真的是玩出了新的高度,下面上干货。

  1、常规赋值与其它语言没区别

if __name__ == "__main__":
name = "蒋乐哥哥"
age = ""
major = "软件工程"
job = "dba" print("{} ,{} ,{} ,{}".format(name,age,major,job))

  2、玩法1): 序列赋值

if __name__ == "__main__":
#name = "蒋乐哥哥"
#age = "16"
#major = "软件工程"
#job = "dba"
name,age,major,job = "蒋乐哥哥","","软件工程","dba"
#是不是感觉自己平时不会这样写、也感觉不到这样写有什么好处、别急我们看一下它的变种 1 name,age,major,job = ("蒋乐哥哥","","软件工程","dba")
#事实上这个变种是比较常用的,用于取出可迭代对象中的各个值、别急它还可以再变 name,age,major,job,*ignore =("蒋乐哥哥","","软件工程","dba","才华横溢","日进斗金","心地善良") print("name={} ,age={} ,major={} ,job={}".format(name,age,major,job))
print("ignore={}".format(ignore)) #输出如下:name=蒋乐哥哥 ,age=16 ,major=软件工程 ,job=dba
#输出如下:ignore=['才华横溢', '日进斗金', '心地善良']

  可以看到对于我们不关注的数据直接被*ignore接收了,但是高手之间出于对一致性的追求,通常不会用ignore这个变量,而是这样写

    name,age,major,job,*_ =("蒋乐哥哥","","软件工程","dba","才华横溢","日进斗金","心地善良")

    print("name={} ,age={} ,major={} ,job={}".format(name,age,major,job))
print("ignore={}".format(_))

  他们对于用不到的数据通常是给一个“_”变量来保存的;也许你还是感觉这面的写法没有意义,太学院派了;那么下面我们来写一个有意义

  的程序,用它来分析linux系统的/etc/passwd文件,这个文件保存的是linux中的用户信息,其中第一列是用户名,最后一列是这个用户对应

  的shell。我们这个程序的目的就是取出用户名和它对应的shell,下面是我电脑上的一份。

root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:997:User for polkitd:/:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
chrony:x:998:996::/var/lib/chrony:/sbin/nologin
uwsgi:x:1000:1000::/home/uwsgi:/bin/bash
nginx:x:1001:1001::/home/nginx:/bin/bash

  想好怎么写了吗?我的代码输出是这样的

python3 main.py
root /bin/bash
bin /sbin/nologin
daemon /sbin/nologin
adm /sbin/nologin
lp /sbin/nologin
sync /bin/sync
shutdown /sbin/shutdown
halt /sbin/halt
mail /sbin/nologin
operator /sbin/nologin
games /sbin/nologin
ftp /sbin/nologin
nobody /sbin/nologin
systemd-network /sbin/nologin
dbus /sbin/nologin
polkitd /sbin/nologin
postfix /sbin/nologin
sshd /sbin/nologin
chrony /sbin/nologin
uwsgi /bin/bash
nginx /bin/bash

  然而我的代码是这样的

if __name__=="__main__":
with open('/etc/passwd') as passwd:
for line in passwd:
name,*_,shell = line.split(':')
print(name,shell,end='')

  上面的代码只是活用了Python的“赋值”代码量就大大减少了。

  3、玩法2): 参数传递

  参数传递也是“赋值”的另一种形式,但是这两种形式是统一的;下面也用一个学院派的例子来举例。假设我们有如下记录

    oprations = [
('add',1,2),
('add',2,3),
('sub',3,2),
('sub',1,1)
]

  第一个字段代表要执行的操作,后面两个字段是操作的参数;也就是说第一个记录的意思就是计算1+2,第三条记录的意思就是计算3-2;

  写个加减法并不难! 先来看一下代有C#口音的写法

def add(a,b):
print("{} + {} = {} ".format(a,b,a+b)) def sub(a,b):
print("{} - {} = {} ".format(a,b,a-b)) if __name__ == "__main__":
oprations = [
('add',1,2),
('add',2,3),
('sub',3,2),
('sub',1,1)
]
for op in oprations:
if op[0]=='add':
add(op[1],op[2])
elif op[0]=='sub':
sub(op[1],op[2])

  看起来没有什么问题,型参通过对op[]索引操作来完成,想想这是天经地义的;看一下pythonic的写法吧

def add(a,b):
print("{} + {} = {} ".format(a,b,a+b)) def sub(a,b):
print("{} - {} = {} ".format(a,b,a-b)) if __name__ == "__main__":
oprations = [
('add',1,2),
('add',2,3),
('sub',3,2),
('sub',1,1)
] for op,*args in oprations:
if op =='add':
add(*args)
elif op =='sub':
sub(*args)

  后都更加的“优雅”,“灵活”;优雅源自于不要再去关心索引,而是直接就能看出参数是怎么传递的;灵活吗?我们再调整一下需求

  “要求add,sub支持三个数据相加减,或两个数据相加减”

def add(a,b,c=0):
print("{} + {} + {} = {} ".format(a,b,c,a+b+c)) def sub(a,b,c=0):
print("{} - {} - {} = {} ".format(a,b,c,a-b-c)) if __name__ == "__main__":
oprations = [
('add',1,2,1),
('add',2,3),
('sub',3,2,1),
('sub',1,1)
] for op,*args in oprations:
if op =='add':
add(*args)
elif op =='sub':
sub(*args)

  由于pythonic的方式并没有用到索引,所以在调用方完全不要改,只要改一下sub和add的定义就好了,就能同时直接两参数,三参数了;

  而使用索引是做不到的!所以呀编码的时候要尽可能的pythonic不要有过多的口音。

  

  

------

讲讲python“=”运算符上的优雅语法的更多相关文章

  1. Python运算符,python入门到精通[五]

    运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算.例如:2+3,其操作数是2和3,而运算符则是“+”.在计算器语言中运算符大致可以分为5种类型:算术运算符.连接运算符.关系运算符.赋值运 ...

  2. Python 运算符与数据类型

    Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...

  3. Python之介绍、基本语法、流程控制

    本节内容 Python介绍 发展史 Python 2 or 3? 安装 Hello World程序 变量 用户输入 模块初识 .pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语 ...

  4. Python入门(上)

    Python入门(上) Python入门(上) 简介 Python 基础语法 行与缩进 注释 运算符 标准数据类型 变量 编程流程 顺序(略) 分支 if 循环 for while break 和 c ...

  5. python运算符与数据类型

    python运算符 Python语言支持以下类型的运算符: 算术运算符 比较(关系)运算符 赋值运算符 逻辑运算符 位运算符 成员运算符 身份运算符 运算符优先级 以下假设变量: a=10,b=20: ...

  6. 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)

    本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上?             成员函数可以被看作是类 ...

  7. Python中的相对导入语法

    Python中支持相对导入语法,即可以相对于某一个package进行导入,具体语法如下: # 导入"./dir2/spam.py", .表示当前目录 from .dir2 impo ...

  8. Python项目中如何优雅的import

    Python项目中如何优雅的import 前言 之前有一篇关于Python编码规范的随笔, 但是写的比较杂乱, 因为提到了import语句, 在篇文章中, 我专门来讲Python项目中如何更好的imp ...

  9. Python运算符及逻辑运算

    基本运算符 运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算.例如:2+3,其操作数是2和3,而运算符则是“+”.在计算器语言中运算符大致可以分为5种类型:算术运算符.连接运算符.关系运 ...

随机推荐

  1. scala 基础语法

    文章内容全部来自:http://twitter.github.io/scala_school/zh_cn/index.html 表达式 scala> 1 + 1 res0: Int = 2 值 ...

  2. ssi框架搭建

    Struts2主要来源于webwork框架,与Struts1相比,在数据传递方面,Struts2提供了更加强大OGNL标签功能,使其能够通过在action中定义变量来直接与jsp页面中的数据进行相互传 ...

  3. js setTimeout setInterval 第三个参数说明

    1.api setTimeout: https://developer.mozilla.org/zh-CN/docs/Web/API/Window/setTimeout var timeoutID = ...

  4. Python学习笔记七:pip

    安装pip: 到github上下载pip:https://github.com/pypa/pip 解压后,在解压出来的文件夹中打开命令行,输入 python setup.py install 安装完毕 ...

  5. django之创建第8-3个项目-数据库数据提取之高级操作

    1.配置test2.html <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...

  6. Photoshop CS6 操作记录

    全局快捷键 橡皮 E 画笔 B 魔棒工具 W 钢笔工具 P 选区工具 M 移动画布 按住Space后鼠标拖动 放大缩小画布 Ctrl+-, Ctrl++ 调出/收回标尺 Ctrl+R 调整画笔大小 [ ...

  7. mysql 常用命令,连接数据库,查看建表语句,批量导入数据,批量更新数据,连接查询

    1. 1)MySQL 连接本地数据库,从cmd中进入mysql命令编辑器: root root分别为用户名和密码 mysql -uroot -proot 2)MySQL 连接本地数据库,用户名为“ro ...

  8. Spring使用内存数据库二

    在上篇<Spring 使用内存数据库>中我们使用Hibernate作为ORM的框架,直接调用Hibernate的API进行相关的持久化操作,但在实际项目中,可能会由于公司规定等原因要求统一 ...

  9. Java读写TXT文本

    public String readTxtFile(String filePath) { StringBuffer appInfolistInput = new StringBuffer(); try ...

  10. VS2010编译Boost 1.56

    (1)首先下载源代码:http://softlayer-dal.dl.sourceforge.net/project/boost/boost/1.56.0/boost_1_56_0.zip 解压到某个 ...