对于Pythonic的概念,众人都有自己的看法,但大家心中都认同一个更具体的指南,即Tim Peters的《The Zen of Python》。在这一篇充满禅意的诗篇中,有几点非常深入人心:

  • 美胜丑,显胜隐,简胜杂,杂胜乱,平胜陡,疏胜密。
  • 找打一个简单问题的一个方法,最好是唯一的方法。
  • 难以解释的实现,源自不好的主意;如有好的主意,它的实现肯定易于解释。
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

(1)Pythonic的定义

遵循Pythonic的代码,看起来像是伪代码。其实,所有伪代码都可以轻易的转换为可执行的Python代码,比如维基百科中的快速排序:

def quicksort(array):
less=[];greater=[]
if len(array)<=1:
return array
pivot=array.pop()
for x in array:
if x<=pivot: less.append(x)
else: greater.append(x)
return quicksort(less)+pivot+quicksort(greater)

结合例子而言,Pythonic也许可以定义为:充分体现Python自身特色的代码风格。

(2)代码风格

举个最常见的例子,在其它语言中(如C语言),两个变量交换需要如下的代码:

int a=,b=;
int tmp = a;
a = b;
b = tmp;

利用Python的packaging/unpackaging机制,Pythonic的代码只需要一行:

a,b = b,a

另外,在遍历一个容器的时候,其他语言代码如下:

length = len(alist)
i =
while i<length:
do_sth_with(alist[i])
i+=

而Pythonic风格的代码如下:

for i in alist:
do_sth_with(i)

灵活的使用迭代器是一种Pyhton风格,但不应过分使用奇技淫巧,比如利用python的Slice语法,可以写出如下代码:

a = [1,2,,3,4]
c = 'abcdef'
print(a[::-1])
print(c[::-1])

实际上,这个时候更好的体现Pythonic的代码是充分利用python库里的reversed()函数的代码。

print(list(reversed(a)))
print(list(reversed(c)))

(3)标准库

写Pythonic程序需要对标准库有充分的理解,特别是内置函数和内置函数数据类型。比如对字符串格式化,一般这样写:

print('Hello %s!' % ('Tom',))

但其实%s是非常影响可读性的,因为数量多了以后很难清除哪一个占位符对应哪一个实参。所以相对应的Pythonic代码是这样的:

print('Hello %(name)s' % {'name':'Tom'})

这样在参数比较多的情况下尤其有用。

#字符串
value = {'greet':'Hello World','language':'Python'}
print('%(greet)s from %(language)s' % value)

%占位符来自于大家的先验知识,对于新手而言,有点‘莫名其妙’,所以更具有Pythonic的风格代码如下:

print('{greet} from {language}'.format(greet='Hello World',language='Python'))

str.format()方法非常清晰的表达了这条语句的意图,而且模板的使用也减少了许多不必要的字符,使得可读性得到了很大的提升。事实上,str.format()也成了Python最为推荐的字符格式化方法,当然也是最Pythonic的。

(4)Pythonic的库或框架

程序员利用Pythonic的库或框架能更加容易、更加自然的完成任务。如果用python编写的库或框架迫使程序员编写累赘的或不推荐的代码,那么可以说它并不Pythonic。现在通常认为Flask这个框架是比较Pythonic的,它的一个Hello World级别的用例如下:

from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return "Hello world!" if __name__="__main__":
app.run()

建议1---理解Pythonic的概念的更多相关文章

  1. 后端技术杂谈11:十分钟理解Kubernetes核心概念

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 本文转自 https://github.com/h2pl/Java-Tutorial 喜欢的 ...

  2. 理解 Keystone 核心概念 - 每天5分钟玩转 OpenStack(18)

    作为 OpenStack 的基础支持服务,Keystone 做下面这几件事情: 管理用户及其权限 维护 OpenStack Services 的 Endpoint Authentication(认证) ...

  3. 转:深入理解JavaScript闭包概念

    闭包向来给包括JavaScript程序员在内的程序员以神秘,高深的感觉,事实上,闭包的概念在函数式编程语言中算不上是难以理解的知识.如果对作用域,函数为独立的对象这样的基本概念理解较好的话,理解闭包的 ...

  4. Java IO 理解流的概念

    Java IO 理解流的概念 @author ixenos 在理解流时首先理解以下概念 1.流的来源和去向一般在构造器指出 2.方法中的形参一般是将流输出到某个位置,读取(INPUT)流从流读出数据( ...

  5. 理解前端模块概念:CommonJs与ES6Module

    前言 现代前端开发每时每刻都和模块打交道.例如,在项目中引入一个插件,或者实现一个供全局使用组件的JS文件.这些都可以称为模块. 在设计程序结构时,不可能把所有代码都放在一起.更为友好的组织方式时按照 ...

  6. 加深理解Java异常概念并熟记5个最常见的运行时异常

    加深理解Java异常概念并熟记5个最常见的运行时异常 说明Error与Exception的联系和区别有哪些? 列举最常见的5个运用时异常. 1.Error和Exception的联系和区别: Error ...

  7. 理解Python闭包概念

    闭包并不只是一个python中的概念,在函数式编程语言中应用较为广泛.理解python中的闭包一方面是能够正确的使用闭包,另一方面可以好好体会和思考闭包的设计思想. 1.概念介绍 首先看一下维基上对闭 ...

  8. 初学Java时没有理解的一些概念

    背景 之前学Java属于赶鸭子上架,草草学习基础语法便直接做课程作业,许多概念问题仍不清楚,故在此梳理一下,主要参考廖雪峰和互联网资料. Java运行方式与JVM Java是介于编译型语言(C++)和 ...

  9. 理解 angular2 基础概念和结构 ----angular2系列(二)

    前言: angular2官方将框架按以下结构划分: Module Component Template Metadata Data Binding Directive Service Dependen ...

随机推荐

  1. XPATH如何选择不包含某一个属性的节点?

    XPATH如何选择不包含某一个属性的节点?今天博主在写一个爬虫的时候就碰到了这个问题. 我们知道选择包含某一特定属性的节点,可以使用例如//tbody/tr[@class]来选择.那么不含某属性的节点 ...

  2. SQLite这么娇小可爱,不多了解点都不行啊

    简介 SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统.它的设计目标是嵌入式的,目前Android和iOS的设备内置的都是SQLite数据库.SQLite虽然娇小,但也支持事务和 ...

  3. 转://ASM与文件系统之间文件传输

    熟悉数据库运维的程序猿都知道,数据的备份重于一切,随着业务的发展,数据量也会越来越大,有时候备份集会放在文件系统上面,有的备份集会放在asm存储上面,实现文件系统到文件系统之间的文件传输很简单,cp或 ...

  4. KazaQ's Socks (找规律)

    #include<iostream> using namespace std; #define ll long long ll n, m; ll t; int main(){ while ...

  5. P2068 统计和(树状数组模板)

    这是一道树状数组题 #include<iostream> using namespace std; ; int tree[maxn], n, m; char h; int x, y; vo ...

  6. 【angularjs】使用angular搭建项目,获取dom元素

    方法一:需要引入jq,否则会报angularJS1 Error: [jqLite:nosel](不建议使用) <div id="testID" class="tes ...

  7. hyperledge工具-configtxgen

    参考http://www.blockchainbrother.com/article/1339 configtxgen是Hyperledger Fabric提供的用于通道配置的实用程序,主要生成以下3 ...

  8. WPF---Binding学习(一)

    转自:http://blog.csdn.net/lisenyang/article/details/18312199 1,Data Binding在WPF中的地位 程序的本质是数据+算法.数据会在存储 ...

  9. Java IO(五)——字符流进阶及BufferedWriter、BufferedReader

    一.字符流和字节流的区别 拿一下上一篇文章的例子: package com.demo.io; import java.io.File; import java.io.FileReader; impor ...

  10. 线程安全之CAS机制详解(分析详细,通俗易懂)

    背景介绍:假设现在有一个线程共享的变量c=0,让两个线程分别对c进行c++操作100次,那么我们最后得到的结果是200吗? 1.在线程不安全的方式下:结果可能小于200,比如当前线程A取得c的值为3, ...