读书笔记 - 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 ...
随机推荐
- FreeRTOS学习笔记2:列表
list.h 列表结构List_t 列表:主要看三个 xLIST:1.5检查列表完整性的.但是需要开启.默认不开启 2:记录列表中列表项的 数量:3:记录当前列表项 索引号:4:列表中的最后一个 列表 ...
- linux下实现keepalived+nginx高可用
1 nginx负载均衡高可用 1.1 什么是负载均衡高可用 nginx作为负载均衡器,所有请求都到了nginx,可见nginx处于非常重点的位置,如果nginx服务器宕机后端web服务将无法提供服务, ...
- 【visio】数据可视化 - 形状数据
visio在对数据处理方面也是有一整套的设施,用户可以用visio存储.管理对象数据,利用数据驱动图形设计,让数据形象化,并在团队沟通的时候清晰地展示数据,沟通数据. 1.属性 每个图形都可以设置多个 ...
- docker 报错 docker: Error response from daemon: driver failed....iptables failed:
现象: [root@localhost test]# docker run --name postgres1 -e POSTGRES_PASSWORD=password -p : -d postgre ...
- Angular 调用百度地图API接口
Angular 调用百度地图API接口 参考原文:https://blog.csdn.net/yuyinghua0302/article/details/80624274 下面简单介绍一下如何在Ang ...
- Requests库网络爬虫实战
实例一:页面的爬取 >>> import requests>>> r= requests.get("https://item.jd.com/1000037 ...
- Cesium 基于MapBox底图加载3DTiles 模型
3DTiles 模型采用 CATIA V5 R22 --->3dxml --->GLB--->B3DM var extent = Cesium.Rectangle.fromDeg ...
- 我来给你讲清楚Pythony广播
初学python广播搞的人头大,今天老师上课讲了一下,茅塞顿开,zt老师nb 首先说一下后向纬度(这个后向纬度书里边称作低维),举例:(3,4,5)后向纬度是:3*4*5或4*5或5 向量广播的条件有 ...
- 微服务、分库分表、分布式事务管理、APM链路跟踪性能分析演示项目
好多年没发博,最近有时间整理些东西,分享给大家. 所有内容都在github项目liuzhibin-cn/my-demo中,基于SpringBoot,演示Dubbo微服务 + Mycat, Shardi ...
- Java常用API——Arrays工具类
介绍:Arrays工具类提供了一些可以直接操作数组的方法,以下是一些常用方法: int binarySearch(type[] a, type key):要求数组a元素升序排列,使用二分法搜索key的 ...