python项目结构
+--- LICENSE
+--- README.rst
+--- requirements.txt
+--- setup.py
+--- sample
|   +--- core.py
|   +--- helpers.py
|   +--- __init__.py
+--- docs
|   +--- conf.py
|   +--- index.rst
+--- tests
|   +--- test_advanced.py
|   +--- test_basic.py
1 核心模块  sample 真正的代码
2 License 许可证
在这个文件中要有完整的许可说明和授权
3 Setup.py 打包和发布管理
4 Requirements File 开发依赖
当然可以通过 setup.py 来设置,这个文件不是必须的 
5 Documentation docs 包的参考文档
6 Test Suite 包的集合和单元测试
7 Makefile 常规的管理任务
    
    ** 样例 Makefile:**
    
    init:
        pip install -r requirements.txt
    
    test:
        py.test tests
    
    PHONY: init test
8 一些其他的常规管理脚本(比如 manage.py 或者 fabfile.py)也放在仓库的根目录下。
常见的一些注意点
0 正确的启动django项目
启动django 项目
django-admin.py startproject samplesite .
注意末尾的 "."
    
    +--- manage.py
    +--- samplesite
    |   +--- settings.py
    |   +--- urls.py
    |   +--- wsgi.py
    |   +--- __init__.py
1 结构化的重要性
拒绝混乱的循环依赖
避免隐含耦合
避免大量使用全局变量或上下文
拒绝面条型的代码 (大量复制-粘贴 的过程代码,且没有合适的分割)
    
减少出现混沌代码 (上百段相似的逻辑碎片,通常是缺乏 合适结构的类或对)
2 模块和包
模块名的定义:
最重要的是,不要使用下划线命名空间,而是使用子模块。
# OK
import library.plugin.foo
# not OK
import library.foo_plugin
模块的导入:
差
    [...]
    from modu import *
    [...]
    x = sqrt(4)  # sqrt是模块modu的一部分么?或是内建函数么?上文定义了么?
    
稍好
    from modu import sqrt
    [...]
    x = sqrt(4)  # 如果在import语句与这条语句之间,sqrt没有被重复定义,它也许是模块modu的一部分。
最好的做法
    import modu
    [...]
    x = modu.sqrt(4)  # sqrt显然是属于模块modu的。 
3 面向对象编程
把有隐式上下文和副作用的函数与仅包含逻辑的函数(纯函数)谨慎地区分开来
会带来以下好处:
    纯函数的结果是确定的:给定一个输入,输出总是固定相同。
    
    当需要重构或优化时,纯函数更易于更改或替换。
    
    纯函数更容易做单元测试:很少需要复杂的上下文配置和之后的数据清除工作。
   
    纯函数更容易操作、修饰和分发。
在很多情况下,面向对象编程是有用甚至必要的 (有相对较长的生命周期)
例如图形桌面 应用或游戏的开发过程中,操作的元素(窗口、按钮、角色、车辆)在计算机内存里拥有相 对较长的生命周期。
4 装饰器
被 ‘装饰’ 的函数或方法会替换原来的函数或方法
    手动装饰
    
    def foo():
        # 实现语句
    
    def decorator(func):
        # 操作func语句
        return func
    
    foo = decorator(foo)  # 手动装饰
    
    @decorator
    def bar():
        # 实现语句
    # bar()被装饰了
5 上下文管理器 with .. as ..
类方法
    class CustomOpen(object):
        def __init__(self, filename):
            self.file = open(filename)
    
        def __enter__(self):
            return self.file
    
        def __exit__(self, ctx_type, ctx_value, ctx_traceback):
            self.file.close()
    
    with CustomOpen('file') as f:
        contents = f.read()
    
    首先被实例化,然后调用它的`__enter__``方法,而且 __enter__ 的返回值在 as f 语句中被赋给 f 。 当 with 块中的内容执行完后,会调用 __exit__` 方法。
     
python 自带的 contextlib
    
    from contextlib import contextmanager
    
    @contextmanager
    def custom_open(filename):
        f = open(filename)
        try:
            yield f
        finally:
            f.close()
    
    with custom_open('file') as f:
        contents = f.read()
6 动态类型
变量 ‘a’ 先代表值1,然后变成 字符串 ‘a string’ , 然后又变为指向一个函数。
避免对不同类型的对象使用同一个变量名
差
    a = 1
    a = 'a string'
    def a():
        pass  # 实现代码
好
    count = 1
    msg = 'a string'
    def func():
        pass  # 实现代码
    使用简短的函数或方法能降低对不相关对象使用同一个名称的风险。即使是相关的不同 类型的对象,也更建议使用不同命名:
差
    items = 'a b c d'  # 首先指向字符串...
    items = items.split(' ')  # ...变为列表
    items = set(items)  # ...再变为集合
7 可变不可变类型
python 中字符串是一个不可变类型, 组合字符串实际都是在一个可变的列表中完成的
    差
        
        # 创建将0到19连接起来的字符串 (例 "012..1819")
        nums = ""
        for n in range(20):
            nums += str(n)   # 慢且低效
        print nums
        
    好
    
        # 创建将0到19连接起来的字符串 (例 "012..1819")
        nums = []
        for n in range(20):
            nums.append(str(n))
        print "".join(nums)  # 更高效
        
    更好
        
        # 创建将0到19连接起来的字符串 (例 "012..1819")
        nums = [str(n) for n in range(20)]
        print "".join(nums)
        
    最好Best
        
        # 创建将0到19连接起来的字符串 (例 "012..1819")
        nums = map(str, range(20))
        print "".join(nums)
字符串的拼接
    
    foo = 'foo'
    bar = 'bar'
    
    foobar = '%s%s' % (foo, bar) # 可行
    foobar = '{0}{1}'.format(foo, bar) # 更好
    foobar = '{foo}{bar}'.format(foo=foo, bar=bar) # 最好
代码风格
1 明确的代码 明确和直接的编码方式
    
    糟糕
    
        def make_complex(*args):
            x, y = args
            return dict(**locals())
    优雅
        
        def make_complex(x, y):
            return {'x': x, 'y': y}
2 每行一个声明
不推荐在同一行代码中写 两条独立的语句
    
    糟糕
    
        print 'one'; print 'two'
        
        if x == 1: print 'one'
        
        if <complex comparison> and <other complex comparison>:
            # do something
   
    优雅
    
        print 'one'
        print 'two'
        
        if x == 1:
            print 'one'
        
        cond1 = <complex comparison>
        cond2 = <other complex comparison>
        if cond1 and cond2:
            # do something
        
3 函数的参数
位置参数, 关键字参数, args*, **kwargs
4 返回值
当一个函数在其正常过程中有多个主要出口点时,它会变得难以调试和返回其结果, 所以保持单个出口点可能会更好。这也将有助于提取某些代码路径,而且多个出口点 很有可能意味着这里需要重构。
    def complex_function(a, b, c):
        if not a:
            return None  # 抛出一个异常可能会更好
        if not b:
            return None  # 抛出一个异常可能会更好
    
        # 一些复杂的代码试着用a,b,c来计算x
        # 如果成功了,抵制住返回x的诱惑
        if not x:
            # 一些关于x的计算的Plan-B
        return x  # 返回值x只有一个出口点有利于维护代码
5 常见的pythonic用语
解包
unpacking
    a, *rest = [1, 2, 3]
    # a = 1, rest = [2, 3]
    a, *middle, c = [1, 2, 3, 4]
    # a = 1, middle = [2, 3], c = 4
创建一个不需要的变量
__
比如,在 解包(Unpacking) )但不需要这个变量,请使用 __
filename = 'foobar.txt'
basename, __, ext = filename.rpartition('.')
注意:
 "_" 常用在作为 gettext() 函数 的别名,也被用在交互式命令行中记录最后一次操作的值。相反,使用双下划线 十分清晰和方便,
 而且能够消除使用其他这些用例所带来的意外干扰的风险。
PEP 8
维护列表的捷径
map() 和 filter() 函数使用一种不同但是更简洁的语法处理列表
赋值永远不会创建新对象
在迭代列表的过程中,永远不要从列表中移除元素
    
    如果有其他变量引用原始列表,则修改它可能会有风险。但如果你真的想这样做,你可以使用 切片赋值(slice assignment) 。
    
    # 修改原始列表的内容
    sequence[::] = [value for value in sequence if value != x]
    # 或者
    sequence[::] = (value for value in sequence if value != x)
读取文件
with .. open ..可以保证自动关闭文件
反斜杠\可以延续代码
更好的解决方案是在元素周围使用括号
糟糕:
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
优雅:
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)
