心路历程

  之前学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. JAVA WEB 解决编码问题的filter

    最近使用Springmvc,GET传输参数的时候,经常出错误,下面介绍添加一个Filter的方法,可以解决这个问题.既支持POST方式也支持GET方式. 首先写一个Filter package com ...

  2. Android Webservices 返回多行多列数据(Dataset)

    对于之前从事.net或者java开发人员,习惯了从后台获取网格数据(多行多列DataTable),但转行从事android开发,难免会不习惯 Android调用Webservice时,如果返回值是一个 ...

  3. 好久不git这么多问题

    本来想把本地项目上传GitHub一下,打开gitbash, git init 之前配置过了 用户名和邮箱以及ssh等 $ git remote add origin https://github.co ...

  4. bootstrap设计站点中加入代码高亮插件

    这款插件的名字叫做google-code-prettify 使用该插件之前的效果: 使用插件之后的效果: 接下来说步骤: (1)下载两个文件 http://codecloud.sinaapp.com/ ...

  5. ADAMS与外部程序通信(Adams Command Server)

    The Adams Command Server is an Adams View (or Adams Car) component that manages communication betwee ...

  6. (原)torch中的序列化

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6591667.html 参考网址: https://github.com/torch/torch7/bl ...

  7. df看到的文件系统容量跟parted看到的分区容量差别较大的解决方法

    下午同事在自己的开发机上遇到题目说到的问题,它看到挂在到/dev/sda磁盘分区5上的ext4文件系统的容量显著小于该分区的大小 df看到的文件系统容量: #df -h /dev/sda5 Files ...

  8. Windows phone 应用开发系列教程(更新中)

    Windows phone 应用开发[1]-Text To Speech        作为开篇章节.第一篇将在如下介绍一些Windows phone比较有意思的东西-Text To Speech[文 ...

  9. log4delphi使用(转)

    转自:http://blog.csdn.net/brightgems/article/details/814042 Log4d是apache下的一个delphi开源子项目,它的设计思想来源于Log4j ...

  10. ML之回归

    一.概述 一元形式: 多元形式: 最小二乘的目标函数