粗粗粗略地过了一遍,大体捞了一些东西出来,大段大段英文太费眼了,回头细读在更新进来
浓缩版,20分钟可大体过完,然后根据自己需要去看详细的吧
整体内容还是很不错的,建议细读英文
PS:文档含有巨量的TODO(没写空白着待补充的),不过但从目录上来看还是很强大滴,相信完善后,会成为一份很牛逼的指南(难度比官方指南高一点点)
第零部分 Getting Started
不解释,不翻译,自个看….真的没啥(每本入门书籍第一章…)
第一部分 Writing Great Code
Structuring Your Project
import 最佳实践
Very bad
1 2 3 4 |
[...] from modu import * [...] x = sqrt(4) # Is sqrt part of modu? A builtin? Defined above? |
Better
1 2 3 |
from modu import sqrt [...] x = sqrt(4) # sqrt may be part of modu, if not redefined in between |
Best
1 2 3 |
import modu [...] x = modu.sqrt(4) # sqrt is visibly part of modu‘s namespace |
Python中关于OOP的 观点
Decorators
1 2 3 4 5 6 7 8 9 10 11 12 13 |
def foo(): # do something def decorator(func): # manipulate func return func foo = decorator(foo) # Manually decorate @decorator def bar(): # Do something # bar() is decorated |
动态类型(Dynamic typing)
Avoid using the same variable name for different things.
Bad
1 2 3 4 |
a = 1 a = ‘a string‘ def a(): pass # Do something |
Good
1 2 3 4 |
count = 1 msg = ‘a string‘ def func(): pass # Do something |
It is better to use different names even for things that are related, when they have a different type:
1 2 3 4 5 |
Bad items = ‘a b c d‘ # This is a string... items = items.split(‘ ‘) # ...becoming a list items = set(items) # ...and then a set |
可变和不可变类型(Mutable and immutable types)
字符串拼接最佳实践
Bad
1 2 3 4 5 |
# create a concatenated string from 0 to 19 (e.g. "012..1819") nums = "" for n in range(20): nums += str(n) # slow and inefficient print nums |
Good
1 2 3 4 5 |
# create a concatenated string from 0 to 19 (e.g. "012..1819") nums = [] for n in range(20): nums.append(str(n)) print "".join(nums) # much more efficient |
Best
1 2 3 |
# create a concatenated string from 0 to 19 (e.g. "012..1819") nums = [str(n) for n in range(20)] print "".join(nums) |
join() is not always best
创建新字符串和修改原有字符串
1 2 3 4 5 6 |
foo = ‘foo‘ bar = ‘bar‘ foobar = foo + bar # This is good foo += ‘ooo‘ # This is bad, instead you should do: foo = ‘‘.join([foo, ‘ooo‘]) |
字符串格式化
1 2 3 4 5 6 |
foo = ‘foo‘ bar = ‘bar‘ foobar = ‘%s%s‘ % (foo, bar) # It is OK foobar = ‘{0}{1}‘.format(foo, bar) # It is better foobar = ‘{foo}{bar}‘.format(foo=foo, bar=bar) # It is best |
Code Style
一般概念(General concepts)
明确的代码
Bad
1 2 3 |
def make_complex(*args): x, y = args return dict(**locals()) |
Good
1 2 |
def make_complex(x, y): return {‘x‘: x, ‘y‘: y} |
每行一个声明
Bad
1 2 3 4 5 6 |
print ‘one‘; print ‘two‘ if x == 1: print ‘one‘ if and : # do something |
Good
1 2 3 4 5 6 7 8 9 10 |
print ‘one‘ print ‘two‘ if x == 1: print ‘one‘ cond1 = cond2 = if cond1 and cond2: # do something |
函数参数
1 2 |
#不解释了 位置参数,默认参数,*args, **args |
Avoid the magical wand(这个肿么翻…)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
原因: Python comes with a very rich set of hooks and tools allowing to do almost any kind of tricky tricks 建议: it is always better to use the most straightforward way to achieve your goal 感受一下: We consider that a Python developer should know about these nearly infinite possibilities, because it grows the confidence that no hard-wall will be on the way. However, knowing how to use them and particularly when not to use them is the most important. Like a Kungfu master, a Pythonista knows how to kill with a single finger, and never to actually do it. 其实就是告诉你,骚年,这玩意你要去学习去了解去掌握,目的是增强实力保持自信,但是不要去用啊 (说的原子弹吧....) |
方言(Idioms)
Idiomatic Python code is often referred to as being Pythonic.
列举了一些:
Unpacking
1 2 3 4 5 6 |
for index, item in enumerate(some_list): # do something with index and item a, b = b, a a, (b, c) = 1, (2, 3) |
忽略接收变量,这里用的是两个下划线,原因
http://docs.python-guide.org/en/latest/writing/style/#create-an-ignored-variable
1 2 |
filename = ‘foobar.txt‘ basename, __, ext = filename.rpartition(‘.‘) |
同一个元素创建一个长度为N的列表
1 |
four_nones = [None] * 4 |
创建一个长度N的嵌套列表
1 |
four_lists = [[] for __ in xrange(4)] |
由列表拼接字符串
1 2 |
letters = [‘s‘, ‘p‘, ‘a‘, ‘m‘] word = ‘‘.join(letters) |
快速查找
1 2 3 4 5 6 7 8 |
d = {‘s‘: [], ‘p‘: [], ‘a‘: [], ‘m‘: []} l = [‘s‘, ‘p‘, ‘a‘, ‘m‘] def lookup_dict(d): #O(1) return ‘s‘ in d def lookup_list(l): #O(n) return ‘s‘ in l |
Zen of Python
1 |
import this |
PEP8
1 2 3 4 |
$ pip install pep8 $ pep8 optparse.py optparse.py:69:11: E401 multiple imports on one line optparse.py:77:1: E302 expected 2 blank lines, found 1 |
惯例(Conventions)
判断值是否等于常量
Bad:
1 2 3 4 5 |
if attr == True: print ‘True!‘ if attr == None: print ‘attr is None!‘ |
Good:
1 2 3 4 5 6 7 8 9 10 11 |
# Just check the value if attr: print ‘attr is truthy!‘ # or check for the opposite if not attr: print ‘attr is falsey!‘ # or, since None is considered false, explicitly check for it if attr is None: print ‘attr is None!‘ |
获取字典元素
Bad:
1 2 3 4 5 |
d = {‘hello‘: ‘world‘} if d.has_key(‘hello‘): print d[‘hello‘] # prints ‘world‘ else: print ‘default_value‘ |
Good:
1 2 3 4 5 6 7 8 |
d = {‘hello‘: ‘world‘} print d.get(‘hello‘, ‘default_value‘) # prints ‘world‘ print d.get(‘thingy‘, ‘default_value‘) # prints ‘default_value‘ # Or: if ‘hello‘ in d: print d[‘hello‘] |
快捷列表操作
Bad:
1 2 3 4 5 6 |
# Filter elements greater than 4 a = [3, 4, 5] b = [] for i in a: if i > 4: b.append(i) |
Good:
1 2 3 |
a = [3, 4, 5] b = [i for i in a if i > 4] b = filter(lambda x: x > 4, a) |
Bad:
1 2 3 4 |
# Add three to all list members. a = [3, 4, 5] for i in range(len(a)): a[i] += 3 |
Good:
1 2 3 4 |
a = [3, 4, 5] a = [i + 3 for i in a] # Or: a = map(lambda i: i + 3, a) |
使用enumerate
1 2 3 4 5 6 |
for i, item in enumerate(a): print i, item # prints # 0 3 # 1 4 # 2 5 |
读文件
Bad:
1 2 3 4 |
f = open(‘file.txt‘) a = f.read() print a f.close() |
Good:
1 2 3 |
with open(‘file.txt‘) as f: for line in f: print line |
超长的行
Bad:
1 2 3 4 5 6 |
my_very_big_string = """For a long time I used to go to bed early. Sometimes, when I had put out my candle, my eyes would close so quickly that I had not even time to say “I’m going to sleep.”""" from some.deep.module.inside.a.module import a_nice_function, another_nice_function, yet_another_nice_function |
Good:
1 2 3 4 5 6 7 8 9 |
#受教了.... my_very_big_string = ( "For a long time I used to go to bed early. Sometimes, " "when I had put out my candle, my eyes would close so quickly " "that I had not even time to say “I’m going to sleep.”" ) from some.deep.module.inside.a.module import ( a_nice_function, another_nice_function, yet_another_nice_function) |
Reading Great Code
感受下:The number one thing that Python programmers do is read code.
再感受一把:One of the secrets of becoming a great Python programmer is to read, understand, and comprehend excellent code.
几个推荐阅读源代码项目
文档(Documentation)
感受一下:Readability is a primary focus for Python developers, in both project and code documentation.
具体还是读原文吧
项目文档组成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
1.A README file at the root directory should give general information to the users and the maintainers. reStructuredText 或 Markdown 2.An INSTALL file is less necessary with python setup.py 3.A LICENSE file should always be present and specify the license under which the software is made available to the public 4.A TODO file or a TODO section in README should list the planned development for the code. 5.A CHANGELOG file or section in README should compile a short overview of the changes in the code base for the latest versions. |
几种文档工具
1 2 3 |
Sphinx(听说最强大....) reStructuredText Markdown(俺的最爱...) |
代码文档建议
Comments clarify code and begin with a hash (#).
In Python, docstrings describe modules, classes, and functions:
1 2 |
def square_and_rooter(x): """Returns the square root of self times self.""" |
注解代码块
Do not use triple-quote strings to comment code.
This is not a good practice, because line-oriented command-line tools such as grep will not be aware that the commented code is inactive.
It is better to add hashes at the proper indentation level for every commented line.
最佳实践:
1 2 |
不用三引号注解代码块 每一行加#来注释 |
测试你的代码(Testing Your Code)
测试一些通用原则
1 2 3 4 5 6 7 8 9 10 11 12 13 |
1.A testing unit should focus on one tiny bit of functionality and prove it correct. 2.Each test unit must be fully independent 3.Try hard to make tests that run fast 4.Learn your tools and learn how to run a single test or a test case 5.Always run the full test suite before a coding session, and run it again after. 6.It is a good idea to implement a hook that runs all tests before pushing code to a shared repository. 7.If you are in the middle of a development session and have to interrupt your work, it is a good idea to write a broken unit test about what you want to develop next. 8.The first step when you are debugging your code is to write a new test pinpointing the bug. 9.Use long and descriptive names for testing functions 10.When something goes wrong or has to be changed, and if your code has a good set of tests, you or other maintainers will rely largely on the testing suite to fix the problem or modify a given behavior. 11.Another use of the testing code is as an introduction to new developers. |
单元测试(Unittest)
Python内置模块, 文档
1 2 3 4 5 6 7 8 |
import unittest def fun(x): return x + 1 class MyTest(unittest.TestCase): def test(self): self.assertEqual(fun(3), 4) |
文档测试(Doctest)
非精细case,只验证主体功能可用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
def square(x): """Squares x. >>> square(2) 4 >>> square(-2) 4 """ return x * x if __name__ == ‘__main__‘: import doctest doctest.testmod() |
相关工具
py.text
$ pip install pytest
Nose unittest的扩展
$ pip install nose
tox
$ pip install tox
Unittest2
$ pip install unittest2
mock
$ pip install mock
Common Gotchas(不懂怎么翻…╮(╯▽╰)╭ )
一些新手可能疑惑的例子
两个例子
1.可变默认参数
What You Wrote
1 2 3 |
def append_to(element, to=[]): to.append(element) return to |
What You Might Have Expected to Happen
1 2 3 4 5 6 7 8 |
my_list = append_to(12) print my_list my_other_list = append_to(42) print my_other_list [12] [42] |
What Does Happen
1 2 |
[12] [12, 42] |
What You Should Do Instead
1 2 3 4 5 |
def append_to(element, to=None): if to is None: to = [] to.append(element) return to |
Python默认参数在函数定义处执行一次,而不是每次函数调用时执行。
2.Late Binding Closures(又一个,延迟绑定闭包?)
What You Wrote
1 2 |
def create_multipliers(): return [lambda x : i * x for i in range(5)] # |
What You Might Have Expected to Happen
1 2 3 4 5 6 7 8 |
for multiplier in create_multipliers(): print multiplier(2) # 任意一个返回的函数被调用时,内部循环i=4 0 2 4 6 8 |
What Does Happen
1 2 3 4 5 |
8 8 8 8 8 |
What You Should Do Instead
1 2 3 4 5 |
from functools import partial from operator import mul def create_multipliers(): return [partial(mul, i) for i in range(5)] |
Python的闭包是延时绑定
选择证书(Choosing a License)
开源证书 列表
证书选择器 入口
第二部分 Scenario Guide
都是介绍性质的,类似工具目录,而且大部分是空的,目前没详细信息
要了解具体,goole相关关键词吧
具体自己翻吧 位置
目录:
Network Applications
Http:
1 |
Requests |
Distributed Systems
1 2 |
ZeroMQ RabbitMQ |
Web Applications
Context
1 |
WSGI |
Frameworks
1 2 3 4 5 |
Django Flask Werkzeug Tornado Pyramid |
Web Servers
1 |
Nginx |
WSGI Servers
1 |
Gunicorn |
Hosting
1 2 3 4 |
PasS (Platform as a service) Heroku DotCloud Gondor |
Templating
1 |
Jinja2 |
HTML Scraping
1 2 |
lxml Requests |
Command Line Applications
1 2 |
Clint docopt |
GUI Applications
1 2 3 4 5 6 7 8 |
Qt Cocoa wxPython GTk Tk Kivy PyjamasDesktop (pyjs Desktop) Camelot |
Databases
1 2 3 |
DB-API SQLAlchemy Django ORM |
Networking
1 2 3 |
Twisted PyZMQ gevent |
Systems Administration
1 2 3 4 5 6 7 |
Fabric Salt Psutil Chef Puppet Blueprint Buildout |
Continuous Integration
1 2 3 4 5 |
Jenkins Buildbot Mule? Tox Travis-CI |
Speed
C Extensions
1 2 3 4 5 |
GIL Cython Pyrex Shedskin Numba |
Threading
1 2 |
Threading Multiprocessing |
Scientific Applications
Tools
1 |
IPython |
Libraries
1 2 3 4 5 6 7 |
NumPy Numba SciPy Matplotlib Pandas Rpy2 PsychoPy |
Image Manipulation
1 |
Python Imaging Library(PIL) |
XML parsing
1 2 |
untangle xmltodict |
QQ群290551701 聚集很多互联网精英,技术总监,架构师,项目经理!开源技术研究,欢迎业内人士,大牛及新手有志于从事IT行业人员进入!