本博文是对<Python代码整洁之道>一书的一些错误进行矫正.
这本书英文名字是<Clean Python Elegant Coding int Python>
这本书的作者是Sunil Kapil. 这本书错误非常多, 真的是非常非常多
我由于没有更多的精力来阅读全本的英文版本,所以可能有些地方的错误需要大家
补充
p6
代码清单1-10 以函数形式对字典排序
def get_sorted_dictionary(users):
"""Sort the nested dictionary"""
if not isinstance(users, dict):
raise ValueError("Not a correct dictionary")
if not len(users):
raise ValueError("Empty dictionary")
users_by_name = sorted(users, key=get_user_name)
return users_by_name
这里的users此时是list实例, 所以应该是isinstance(users, list)
p7
代码清单1-12 以更具可读性的代码读取一个csv文件
import csv
with open('employee.txt', mode='r') as csv_file:
csv_reader = csv.DictReader(csv_file)
line_count = 0
process_salary(csv_reader)
这里是一个employee.txt的example, 可以写入后改为csv文件
第一行第表头columns,其余行是表信息
name,country,age,salary
clarence,US,23,20k
bob,Canada,29,40k
ruby,Japan,28,16k
这里打开文件应该是employee.csv文件, 原著作者应该是创建并写入employee.txt然后修改后缀名为csv, 所以写代码的时候忽略了
p11
7 比较类型时更偏向使用isintance()方法而不是type()
user_ages = {"Larry": 35, "Jon": 89, "Imli": 12}
type(user_ages) == dict
这里最好是type(user_ages) is dict
p22
1.3.2 不要使用复杂的列表推导
ages = [1, 34, 5, 7, 3, 57, 356]
old = [age for age in ages if 10 < age < 100 and age is
not None]
如果要校验,那么写在and逻辑运算符前面,注意短路
p23
1.3.3 应该使用lambda吗
关于函数功能描述有误(原版和译版)
这里如果是找到列表中含有最小值的元素,应该这样
def min_val(data):
"""Find minimum value from the data list."""
return min(data, key=lambda x:len(x))
改为return min(data, key=lambda x: min(x))
p27
1.3.6 为什么range函数在Python3中更好
译者翻译有误
原文是:
If you have worked with Python 2, you might have used xrange. In Python 3,
xrange has been renamed to range with some extra features. range is
similar to xrange and generate an iterable.
译文里range类似于xrange并生成一个迭代器
应该是range与xrange相似, 并且产生一个可迭代对象
, 这也许会对初中级的python使用者产生困扰.
p32
1.4.4 只处理特定的异常
如下是译者自己附加的解释, 但except Exception:并不是处理所有异常
(except: 或者except Exception将处理所有的异常, 它会导致代码隐藏不想隐藏的关键错误
或异常.)
- 官方文档如下关于exception Exception的描述
exception Exception
All built-in, non-system-exiting exceptions are derived from this
class.
All user-defined exceptions should also be derived from this class.
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
| +-- ModuleNotFoundError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- EncodingWarning
+-- ResourceWarning
except Exception:捕获所有的非系统退出异常, 除此之外还有系统退出、键盘中断、生成器退出异常
except: 捕获所有类型的异常
p33
1.4.4 只处理特定的异常
这里描述错误, 应该是Get list of even numbers from given list
def get_even_list(num_list):
"""Get list of odd numbers from given list."""
return [item for item in num_list if item%2==0]
p39
2.1.1 使用集合
集合是无序不重复元素, 不支持索引、切片以及任何序列行为
序列是字符串、列表和元组,集合不是序列
如下是原文和译文
原文:
They don’t allow duplicates.
• You can’t access set elements using an index.
• Sets can access elements in O(1) time since they use
hashtables.
• Sets don’t allow some common operations that lists do
like slicing and lookups.
• Sets can sort the elements at insertion time.
译文:
• 集合元素不能重复
• 不支持索引访问集合里的元素
译者翻译错误,集合底层就是散列表,而不是使用散列表
• 集合使用散列表之后,可以在O(1)时间内访问元素
译者翻译错误,"纠正"了原文,很遗憾,也是错误的,集合不支持,原文是正确的
• 集合支持一些常见的操作,如列表的切片和查询
集合是无序的,这条是不成立的
• 集合可以在插入元素时对元素进行排序
p39
代码清单2-1 使用集合访问数据
译者对于描述信息出现了"直译"
正确为该项在内存中的位置的因素之一是对象的哈希值
原文:
Sets are implemented using hashtables, so whenever a new item is
added to a set, the positioning of the item in memory is determined by
the hash of the object.
译文:
集合是使用散列表实现的,因此每当一个新项添加到集合中时, 该项在内存中的
位置由散列的对象确定.
p39
代码清单2-2 使用集合去重
描述错误集合
原文:
集合可用作字典的键, 也可以使用集合用作其他数据结构的键, 如列表(list)
集合是可变的, 不可哈希,不能用于字典的键
In [1]: l = {1, 2, 3}
In [2]: l.__hash__ is None
Out[2]: True
In [3]: getattr(l, "__hash__") is None
Out[3]: True
In [4]: callable(l.__hash__)
Out[4]: False
In [5]: hash(l)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Input In [5], in <cell line: 1>()
----> 1 hash(l)
TypeError: unhashable type: 'set'
p45
代码清单2-9 使用列表返回素数
代码错误, 多出来一行
正确示例如下
def get_prime_numbers(lower, higher):
primes = []
for num in range(lower, higher + 1):
is_prime = True
for item in range(2, int(num ** 0.5) + 1):
if num % item == 0:
is_prime = False
break
if is_prime:
primes.append(num)
return primes
if __name__ == '__main__':
print(get_prime_numbers(1, 7))
p45
代码清单2-10 对素数使用生成器
is_prime函数比较奇怪,修改后如下
import math
def is_prime(num):
for item in range(2, int(math.sqrt(num)) + 1):
if num % item == 0:
return False
return True
p48
2.1.6 使用Python的内置函数
译者对于csv模块描述信息出现了"直译"
正确译文
csv
Use csv for reading and writing CSV files. It will save you lot of time instead
of writing your own methods while reading files.
csv模块用于读写csv文件. 它能帮助你读写时节省大量的时间,你不需要重复造轮子
p50
代码清单2-15 使用__future__
from __future__ import division
p54
2.2.3 有序字典、默认字典、普通字典
对于描述部分有"直译"
As of Python 3.6, dicts are now ordered by insertion order, which
actually reduces the usefulness of ordereddict
python3.6之后(包含), 字典根据插入顺序排序, 所以ordereddict自然就基本上没有
用武之地了,除非要兼容
p64
代码清单3-5 引发一个异常而不是None
正确代码如下
def read_lines_for_python(file_name, file_type):
if file_type not in ("txt", "html"):
raise ValueError("Not correct file format")
if not file_name:
raise IOError("File Not Found")
filename = "".join([file_name, ".", file_type])
with open(filename, "r") as fileread:
for line in fileread:
if "python" in line:
return "Found Python"
if __name__ == '__main__':
if not read_lines_for_python("file_without_python_name", "pdf"):
print("Python keyword doesn't exists in file")
p66
代码清单3-11 显示地返回None
译文出现"直译"
正确译文如下
Here you expect the result to be a value in the sum function, which is
misleading because it could return None or a sum of two numbers. So, you
always need to check the result for None, which is too much noise in the
code and makes the code more complex over time
你期望sum函数返回的是一个值, 如果返回None或者两数之和会是一种误导
在这种情况下,你需要不断的检查sum的返回结果是否为None. 代码会随着时间变得
混乱和复杂
p67
代码清单3-13 显示地返回None
代码清单3-14 不显示地返回None
原文判断numbers是list及其子类的实例逻辑错误
对于函数功能描述错误
正确如下
def find_odd_number(numbers):
odd_numbers = []
if not isinstance(numbers, list):
return None
for item in numbers:
if item % 2 != 0:
odd_numbers.append(item)
return odd_numbers
num = find_odd_number([2, 4, 6, 7, 8, 10])
num = find_odd_number((2, 4, 6, 7, 8, 10))
num = find_odd_number([2, 4, 6, 8, 10])
"""
This function by default returns None if it does not find an odd
number. The function also returns None if the type of numbers is not a list.
如果numbers的类型不是list,那么返回的是[]空列表,不是None
"""
p68
3.1.5 编写函数时注意防御
代码清单3-15 Python中的日志记录
代码清单中代码有好几处错误,正确如下所示
import os
import logging
from logging import StreamHandler
current_filename = os.path.basename(__file__)
logger = logging.getLogger(current_filename)
handler = StreamHandler()
handler.setLevel(logging.WARNING)
format_c = logging.Formatter("%(name)s---%(levelname)s---%(message)s")
handler.setFormatter(format_c)
logger.addHandler(handler)
def division(divident, divisor):
try:
return divident/divisor
except ZeroDivisionError:
logger.error("Zero Division Error")
if __name__ == '__main__':
num = division(4, 0)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)