读书笔记 - The Hitchhiker's Guide to Python
网址
http://docs.python-guide.org/en/latest/
Reuqests库的作者写的经验
1. 项目需要一个好的结构
https://www.kennethreitz.org/essays/repository-structure-and-python
https://github.com/kennethreitz/samplemod
2. 组织糟糕的项目的一些标志(Some signs of a poorly structured project include):
2.1 多重和混乱的循环依赖(Multiple and messy circular dependencies)
furn.py
class Table():
def isdoneby():
pass
class Chair():
def isdoneby():
pass
workers.py
class Carpenter():
def whatdo():
pass
如果table.isdoneby()依赖import Carapenter才能执行;相反地,carpenter.whatdo()又要依赖import Table和Chiar。如果一开始就import,出现循环引入。
一个能解决问题但是不好的技巧是在方法或者函数里import。
2.2 隐藏的耦合(Hidden coupling)
如果Table内部的改变都使Carpenter的某些test cases不通过,那么Table和Carpenter的耦合性过大,Table的内部改变影响到Carpenter。
2.3 重度使用全局变量、状态、上下文(Heavy usage of global state or context)
2.4 面条代码(Spaghetti code)和馄饨代码(Ravioli code)
https://blog.csdn.net/godsme_yuan/article/details/6594013
面条代码:冗长,控制结构复杂(例如充满if,for),混乱而难以理解的代码。本人觉得,在编辑器里这些代码有非常多的guidelines垂下来,非常形象的”面条“。
馄饨代码:程序由许多小的,松散耦合的部分(方法,类,包等)组成。没有遵循高内聚,低耦合。书中举了个例子:如果你不知道什么时候用必须用FurnitureTable,AssetTable和TableNew,那么这些代码就是混沌代码一块一块的,很松散。
3. Module的艺术
3.1 Being able to tell immediately where a class or function comes from, as in the modu.func idiom, greatly improves code readability and understandability in all but the simplest single file projects.
3.2 In many languages, an include file directive is used by the preprocessor to take all code found in the file and‘copy’ it into the caller’s code. It is different in Python: the included code is isolated in a module namespace, whichmeans that you generally don’t have to worry that the included code could have unwanted effects, e.g. override an
existing function with the same name (即import module, 可用module.func)
3.3 不要用from module import *
4. package的艺术
4.1 文件夹里有__init__.py就视作一个包
4.2 A file modu.py in the directory pack/ is imported with the statement import pack.modu. This statement will look for an _init_.py file in pack, execute all of its top-level statements. Then it will look for a file named pack/modu.py and execute all of its top-level statements. After these operations, any variable, function, or class defined in modu.py is available in the pack.modu namespace.
4.3 当项目复杂性上升的时候,可能有sub-packages或者sub-sub-packages在一个很深的目录层次结构里面(包里有包,嵌套关系)。这种情况下,import一个在很深层次的包里的module时,会执行全部_init_.py文件(files);所以,如果包(package)和包里的包(sub-package)不共享代码,最好把__init__.py置空。
4.4 用import very.deep.module as mod 代替 import very.deep.module
5. Pure function
Pure functions are more efficient building blocks than classes and objects for some architectures because they have no context or side-effects
6. 装饰器(Decorators)
6.1 A decorator is a function or a class that wraps (or decorates) a function or a method. The ‘decorated’ function or method will replace the original ‘undecorated’ function or method. Because functions are first-class objects in Python, this can be done ‘manually’, but using the @decorator syntax is clearer and thus preferred.
6.2 This mechanism is useful for separating concerns and avoiding external un-related logic ‘polluting’ the core logic of the function or method.
6.3 A good example of a piece of functionality that is better handled with decoration is memoization or caching: you want to store the results of an expensive function in a table and use them directly instead of recomputing them when they have already been computed. This is clearly not part of the function logic.
7. 上下文管理(Context Managers)
7.1 A context manager is a Python object that provides extra contextual information to an action. 用with语句.
with open('file.txt') as f:
contents = f.read()
7.2 有两种实现方法:class和generator. Since the two approaches appear the same, we should follow the Zen of Python to decide when to use which. The class approach might be better if there’s a considerable amount of logic to encapsulate. The function approach might be better for situations where we’re dealing with a simple action.
CustomOpen is first instantiated and then its _enter_ method is called and whatever _enter_ returns is assigned to f in the as f part of the statement. When the contents of the with block is finished executing, the _exit_ method is then called.
# class实现上下文管理
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()
The custom_open function executes until it reaches the yield statement. It then gives control back to the with statement, which assigns whatever was yield‘ed to f in the as f portion. The finally clause ensures that close() is called whether or not there was an exception inside the with
# generator实现上下文管理
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()
8. 动态类型(Dynamic typing)
- Python是动态类型语言,也即是variables没有fixed type,只是引用;
- The dynamic typing of Python is often considered to be a weakness, and indeed it can lead to complexities and hardto-debug code. 例如变量a可以是任何object.
1. Avoid using the same variable name for different things.
# Bad
a = 1
a = 'a string'
def a():
pass # Do something
# Good
count = 1
msg = 'a string'
def func():
pass # Do something
2. it may be a good discipline to avoid assigning to a variable more than once
#Bad
items = 'a b c d' # This is a string
items = items.split(' ') # ..becoming a list
items = set(items) # ... and then a set
9. 可变类型和不可变类型(Mutable and immutable types)
9.1 像list这些可变对象,list.append()和list.pop()是原地修改list
9.2 像6这个integer,是不可变对象, x = x + 1会是x指向另一个对象。
my_list = [1, 2, 3]
my_list[0] = 4
print(my_list) # [4, 2, 3] <- The same list has changed
x = 6
x = x + 1 # The new x is another object
9.3 string在Python中是不变的
#Bad
# 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
# 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
# Better
# create a concatenated string from 0 to 19 (e.g. "012..1819")
# list comprehension
nums = [str(n) for n in range(20)]
print("".join(nums))
# Best
# create a concatenated string from 0 to 19 (e.g. "012..1819")
# map
nums = map(str, range(20))
print("".join(nums))
One final thing to mention about strings is that using join() is not always best. In the instances where you are creating a new string from a pre-determined number of strings, using the addition operator is actually faster, but in cases like above or in cases where you are adding to an existing string, using join() should be your preferred method.
foo = 'foo'
bar = 'bar'
foobar = foo + bar # This is good
foo += 'ooo' # This is bad, instead you should do:
foo = ''.join([foo, 'ooo'])
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
10. General concepts
不要炫技, Explicit code. While any kind of black magic is possible with Python, the most explicit and straightforward manner is preferred.
Avoid the magical wand. it is always better to use the most straightforward way to achieve your goal.
Like a kung fu master, a Pythonista knows how to kill with a single finger, and never to actually do it.
#Bad
def make_complex(*args):
x, y = args
return dict(**locals())
#Good
def make_complex(x, y):
return {'x':x, 'y':y}
第二个Good的写法,可读性强
it is bad practice to have two disjointed statements on the same line of code.
#Bad
print('one'); print('two')
if x == 1: print('one')
if <complex comparison> and < other complex comparison>:
# Do Something
#Good
print('one')
print('two')
if x == 1:
print('one')
cond1 = <complex comparison>
cond2 = <other complex comparision>
if cond1 and cond2:
# Do Something
Function arguments(函数参数)
关于Positional arguments(位置参数).
Positional arguments are mandatory and have no default values.
def send(message, recipient):
pass
def point(x, y):
pass
# Bad, 虽然可以这样做
send(recipient='World', message='Hello')
point(y=2, x=1)
# Good, straightforward并且可读性高
send('Hello', 'World') and point(1, 2)
关于Keyword arguments(关键字参数)
Keyword arguments are not mandatory and have default values. for optional parameters sent to the function.
def send(message, to, cc=None, bcc=None)
arbitrary argument list
In the function body, args will be a tuple of all the remaining positional arguments.
def send(message, *args):
pass
# send('a', 'b', 'c' ,'d'), args就等于('b', 'c', 'd')
arbitrary keyword argument dictionary
kwargs will be a dictionary of all the passed named arguments that have not been caught by
other keyword arguments in the function signature.
We are all responsible users.
Python里没有真正的private属性, 所以开发者和用户有责任去遵守约定(conventions).
Rather, instead of relying on concrete walls erected by the developers between their code and other’s, the Python community prefers to rely on a set of conventions indicating that these elements should not be accessed directly.
返回值Returning values
保持单一return就好
def complex_function(a, b, c):
if not a:
return None # Raising an exception might be better
if not b:
return None # Raising an exception might be better
if not c:
return None # Raising an exception might be better
# Plan A: Compute X from a, b and c
x = a + b + c
if not x:
# Plan B for computing x
return x # One single exit point for the returned value x will help when maintaining the code.
11. Idioms(习惯用法)
A programming idiom, put simply, is a way to write code.
读书笔记 - The Hitchhiker's Guide to Python的更多相关文章
- The Hitchhiker’s Guide to Python! — The Hitchhiker's Guide to Python
The Hitchhiker's Guide to Python! - The Hitchhiker's Guide to Python The Hitchhiker's Guide to Pytho ...
- 读书笔记:编程小白的第一本python入门书
书名:编程小白的第一本python入门书 作者:侯爵 出版社/出处:图灵社区 年份:2016年 封面: 感想: 本书短小精悍,精华部分在于给编程小白打了鸡血的同时输出了一种“高效学习法的思想”. 个人 ...
- <读书笔记>001-以解决问题为导向的python编程实践
以解决问题为导向的python编程实践 0.第0章:计算机科学 思考:计算机科学是否为计算机编程的简称? 编程的困难点:1.同时做2件事(编程语言的语法.语义+利用其解决问题) 2.什么是好程序(解 ...
- Web Scraping with Python读书笔记及思考
Web Scraping with Python读书笔记 标签(空格分隔): web scraping ,python 做数据抓取一定一定要明确:抓取\解析数据不是目的,目的是对数据的利用 一般的数据 ...
- 读书笔记汇总 --- 用Python写网络爬虫
本系列记录并分享:学习利用Python写网络爬虫的过程. 书目信息 Link 书名: 用Python写网络爬虫 作者: [澳]理查德 劳森(Richard Lawson) 原版名称: web scra ...
- 【读书笔记与思考】《python数据分析与挖掘实战》-张良均
[读书笔记与思考]<python数据分析与挖掘实战>-张良均 最近看一些机器学习相关书籍,主要是为了拓宽视野.在阅读这本书前最吸引我的地方是实战篇,我通读全书后给我印象最深的还是实战篇.基 ...
- 《Python神经网络编程》的读书笔记
文章提纲 全书总评 读书笔记 C01.神经网络如何工作? C02.使用Python进行DIY C03.开拓思维 附录A.微积分简介 附录B.树莓派 全书总评 书本印刷质量:4星.纸张是米黄色,可以保护 ...
- 转载-《Python学习手册》读书笔记
转载-<Python学习手册>读书笔记 http://www.cnblogs.com/wuyuegb2312/archive/2013/02/26/2910908.html
- python高级编程读书笔记(一)
python高级编程读书笔记(一) python 高级编程读书笔记,记录一下基础和高级用法 python2和python3兼容处理 使用sys模块使程序python2和python3兼容 import ...
随机推荐
- c语言thread用法记录。
https://blog.csdn.net/hitwengqi/article/details/8015646 先是c++11之前的 1.最基础,进程同时创建5个线程,各自调用同一个函数 #inclu ...
- Java - 集合 - Map
Map 1.Map实现类:HashMap.Hashtable.LinkedHashMap.TreeMap HashMap 新增元素/获取元素 1 void contextLoads() { 2 //声 ...
- MySQL执行外部sql脚本文件的命令
sql脚本是包含一到多个sql命令的sql语句,我们可以将这些sql脚本放在一个文本文件中(我们称之为“sql脚本文件”),然后通过相关的命令执行这个sql脚本文件.基本步骤如下:1.创建包含sql命 ...
- 主席树板子 p2104
#include<cstdio> #include<algorithm> #include<vector> using namespace std; ; int n ...
- Intellij Idea2019版本激活,目前可以激活到2089,解决失效问题(非商业用途)
目录 Intellij Idea2019版本激活,目测可以激活到2089!! 前言-此教程仅用作个人学习,请勿用于商业获利,造成后果自负!!! 步骤(直接激活新下载的) 成功 注意(不想重新下载的小伙 ...
- poi处理excel自定义日期格式
poi读取excel自定义时间类型时,读取到的是CELL_TYPE_NUMERIC,即数值类型,这个时候如果直接取值的话会发现取到的值和表格中的值不一样,这时应该先判断值是否是时间或者日期类型再进行处 ...
- 题解 SP7579 YOKOF - Power Calculus
SP7579 YOKOF - Power Calculus 迭代加深搜索 DFS每次选定一个分支,不断深入,直至到达递归边界才回溯.这种策略带有一定的缺陷.试想以下情况:搜索树每个节点的分支数目非常多 ...
- Sql性能优化梳理
前言 先简单梳理下Mysql的基本概念,然后分创建时和查询时这两个阶段的优化展开. 1.0 基本概念简述 1.1 逻辑架构 第一层:客户端通过连接服务,将要执行的sql指令传输过来 第二层:服务器解析 ...
- MyBatis操作mysql数据库查询出来是时间戳的问题
在pojo类中用java.sql.Date接收就能正常显示
- Block Chain Learning Notes
区块链是什么 区块链技术是由比特币创造的,本文也将从比特币开始进行引导,一步一步告诉大家什么是区块链.如果你想立马知道区块链是什么,也可以直接转到文章末尾的区块链定义. 区块链,可能是当下最有前景又充 ...