1.Python 3.8中yield 的变化
随着Python 3.8的发布,对该语言进行了一些重大的补充和突破性的改变。在生成器表达式和理解式中使用yield 时,行为有了变化。
以此为例。
MAGIC_NUMBERS = {(yield num) for num in SECRET_NUMBERS if can_amaze(num)}
这在Python 3.7之前是允许的(尽管它仍然会抛出一个DeprecationWarning )--而在Python 3.8中变成了一个SyntaxError 。
在使用yield 时,还有一些不一致的地方需要注意。例如,在 Python 2.7 中,这不会抛出任何错误。
但是,如果像这样在列表理解中使用yield ,Python 2.7 会抛出一个SyntaxError 说'yield' outside function 。
odd _numbers =[(yield num) for num in range(100) if num % 2 == 0]
在 Python 3.x (直到 Python 3.7) 中,所有上述的操作都是允许的。从 Python 3.8 开始,这已经成为非法的了。要阅读关于这个问题的更多信息,请查看这个错误报告。
2.当assert 失败时引发另一个异常是无效的
当一个assert 条件不满足时,它总是引发一个AssertionError 。即使明确地引发另一个内置的异常,也是无效的。
例子:
assert isinstance(num_channels, int), ValueError(
'Number of image channels needs to be an integer'
)
这里,当assert失败时,用户会期待一个像这样的ValueError 。
ValueError: Number of image channels needs to be an integer
但相反,当条件失败时,上面的代码会抛出一个AssertionError 。
AssertionError: Number of image channels needs to be an integer
3.使用sqrt 方法进行毕达哥拉斯式计算
使用标准公式sqrt(a**2 + b**2) 计算斜边的长度,如果a 或b 或两者都很大,可能会导致OverflowError 。
比如说:
def get_hypotenuse(a, b):
return math.sqrt(a**2 + b**2)
get_hypotenuse(2e154, 1e154)
运行这个公式会有这样的输出:
OverflowError: (34, 'Numerical result out of range')
为了避免这种情况,请使用math 模块中的hypot 方法。
即使提供给hypot 方法的一方(或两方)太大,无法存储(例如2e308 和1e154 ),也不会出现任何运行时错误,返回值为inf 。
4.空模块
让空模块到处乱放绝不是个好主意,因为它不必要地填充了项目。如果该文件由于某种原因是必要的,那么该文件应该有文件说明,解释它为什么在那里。
可读性很重要✨
5.用debug 作为运行的Flask应用True
调试器是用来在本地使用的,在生产中不应该启用。
当flask应用在调试模式下运行时,如果应用使用交互式调试器(如werkzeug ),攻击者可以获得对运行该应用的服务的访问。在这种情况下,应用程序就容易受到远程代码执行的攻击,因为任何任意代码都可以通过互动调试器运行。
下面是一个关于该漏洞的例子。
from flask import Flask
app = Flask(__name__)
@app.route('/crash')
def main():
...
raise Exception()
app.run(debug=True)
推荐的方法是删除启用调试器的语句,或者在生产环境中设置环境变量来禁用它。这里有一篇关于Patreon如何因为这个漏洞而被黑的文章。