发布时间:2023-04-17 11:30
当我们开始学习Python时,我们会养成一些不良编码习惯,而更可怕的是我们连自己也不知道。
我们学习变成的过程中,大概有会这样的经历: 写的代码只能完成了一次工作,但后来再执行就会报错或者失败,令人感到懊恼,
或者偶然发现一个内置函数可以让你的工作更轻松时,瞬间豁然开朗。
我们中的大多数人仍然有很多使用Python的坏习惯,这些习惯在我们学习python的前期就存在,今天你可以通过下面的章节来解
决它们。
当我们为了省事,我们临时加载包,使用:
1.from xyz import *
这不是一个好习惯,原因很多。仅举几个例子:
1.效率低下。如果该模块有大量的对象,需要等待很长时间,直到所有的object都被导入。
2.可能导致变量名之间的冲突。当你使用 *时,我们不知道导入哪些对象以及它们的名字。
如何处理这个问题?导入你打算使用的特定对象
1.# Using import *
python学习交流Q群:906715085###
3.from math import *
5.print(floor(2.4))
7.print(ceil(2.4))
9.print(pi)
11.# Good
13.import math
15.from math import pi
17.print(math.floor(2.4))
19.print(math.ceil(2.4))
21.print(pi)
我已经忽略这个问题很长时间了~
在Pycharm中写python时候,总是提示我错误,嗯,你懂的,就是那些丑陋的下划线。我不应该使用 裸except。PEP 8指南中并
不推荐 裸except。
裸except的问题是它会捕捉SystemExit和KeyboardInterrupt异常,从而不能使用Control-C来中断程序。
下次你使用try/except时,在 except子句中会报错。
1.# Try - except
3.# 错误写法
5.try:
7.driver.find_element(...)
9.except:
11.print("Which exception?")
13.# 提倡写法
15.try:
17.driver.find_element(...)
19.except NoSuchElementException:
21.print("It's giving NoSuchElementException")
23.except ElementClickInterceptedException:
25.print("It's giving ElementClickInterceptedException")
提倡我们主动使用已经成熟包,这样写可以使Python更简洁、更有效率。
其中最应该用于数学计算的包是Numpy。Numpy可以帮助你比 for循环更快地解决数学运算。
假设我们有一个 random_scores数组,我们想得到没有通过考试的人的平均分数(分数<60)。让我们尝试用 for循环来解决这个问题。
1.import numpy as np
3.random_scores = np.random.randint(1, 100, size=10000001)
5.# bad (solving problem with a for loop)
7.count_failed = 0
9.sum_failed = 0
11.for score in random_scores:
13. if score < 70:
15. sum_failed += score
17. count_failed += 1
19.print(sum_failed/count_failed)
现在让我们用Numpy来解决这个问题。
1.# Good (solving problem using vector operations)
3.mean_failed = (random_scores[random_scores < 70]).mean()
5.print(mean_failed)
如果你同时运行两者,你会发现Numpy更快。为什么呢?因为Numpy将我们的操作向量化了。
大家都知道的好做法是,我们用Python打开的每个文件都必须关闭。
这就是为什么我们每次处理文件时都要使用 open, write/read, close。这很好,但是如果 write/read方法抛出一个异常,文件就不会被关闭。
为了避免这个问题,我们必须使用 with语句。这样,即使有异常,也会关闭该文件。
1.# Bad
3.f = open('dataset.txt', 'w')
5.f.write('new_data')
7.f.close()
9.# Good
11.with open('dataset.txt', 'w') as f:
13.f.write('new_data')
PEP8是一份每个学习Python的人都应该阅读的文件。它提供了关于如何编写Python代码的指南和最佳实践(本文中的一些建议来
自PEP8)
对于那些刚接触Python的人来说,这个准则可能会让他们感到担心,不过大可不必担心,一些PEP8规则被纳入IDE中(我就是这
样知道 裸except规则的)。
假设你在使用Pycharm。如果你写的代码没有遵循PEP8的准则,你会看到下面图片中那些难看的下划线。
如果你把鼠标悬停在下划线上,你会看到关于如何修复它们的提示。
在我的例子中,我只需要在 ,和 :后面添加一个空格。
1.# Good
3.my_list = [1, 2, 3, 4, 5]
5.my_dict = {'key1': 'value1', 'key2': 'value2'}
7.my_name = "Frank"
我还把我的变量 x的名字改为 my_name。这不是Pycharm建议的,但PEP8建议使用容易理解的变量名。
我想大多数人都知道在使用字典时, .keys和 .values方法的作用。
如果你不知道的话,让我们来看看。
1.dict_countries = {'USA': 329.5, 'UK': 67.2, 'Canada':
2.>>>dict_countries.keys()
3.dict_keys(['USA', 'UK', 'Canada'])
4.>>>dict_countries.values()
5.dict_values([329.5, 67.2, 38])
这里的问题,我们没有理解并正确使用它们。
假设我们想循环浏览 dictionary 并获得 keys。你可能会使用 .keys 方法,但是你知道你可以通过在字典中循环获得键吗?在这种
情况下,使用 .keys 将是不必要的。
1.# Not using .keys() properly
3.# Bad
5.for key in dict_countries.keys():
7. print(key)
9.# Good
11.for key in dict_countries:
13. print(key)
另外,我们可能会想出一些变通的办法来获得字典的值,但这可以用 .items()方法轻松获得。
1.# Not using .items()
3.# Bad
5.for key in dict_countries:
7. print(dict_countries[key])
9.# Good
11.for key, value in dict_countries.items():
13. print(key)
15. print(value)
当你想在一个已经定义好的序列的基础上创建一个新的序列(列表、字典等)时,comprehension提供了一个更短的语法。
比如说我们想把我们的 countries列表中的所有元素都小写。
虽然你可以用一个 for循环来做这件事,但你可以用一个列表理解来简化事情。
理解是非常有用的,但是不要过度使用它们! 记住 Python 的禅宗。“简单比复杂好”。
1.# Bad
3.countries = ['USA', 'UK', 'Canada']
5.lower_case = []
7.for country in countries:
9. lower_case.append(country.lower())
11.# Good (but don't overuse it!)
13.lower_case = [country.lower() for country in countries]
我们作为初学者最先学习的函数之一是 range和 len,所以难怪大多数人在循环浏览列表时都有写 range(len())的坏习惯。
假设我们有一个 countries, populations列表。如果我们想同时遍历两个列表,你可能会使用 range(len())。
1.# Using range(len())
3.countries = ['USA', 'UK', 'Canada']
5.populations = [329.5, 67.2, 38]
7.# Bad
9.for i in range(len(countries)):
11. country = countries[i]
13. population = populations[i]
15. print(f'{country} has a population of {population} million people')
虽然这可以完成工作, 但你可以使用 enumerate来简化事情 (或者更好的是, 使用 zip函数来配对两个列表中的元素)
1.# OK
3.for i, country in enumerate(countries):
5. population = populations[i]
7. print(f'{country} has a population of {population} million people')
9.# Much Better
11.for country, population in zip(countries, populations):
13. print(f'{country} has a population of {population} million people')
我们在Python中最先学会的东西之一可能是如何用 +运算符连接字符串。
这是在 Python 中连接字符串的一种有用但低效的方法。此外,它也不是那么好看–你需要连接的字符串越多,你使用的+就越多。
你可以使用 f-string来代替这个运算符。
1.# Formatting with + operator
3.# Bad
5.name = input("Introduce Name: ")
7.print("Good Morning, " + name + "!")
9.# Good
11.name = input("Introduce Name: ")
13.print(f'Good Morning, {name}')
string最大的特点是,它不仅对连接有用,而且有不同的应用。
如果你把一个可变的值(如list)作为一个函数的默认参数,你会看到一些意想不到的结果。
1.# Bad
2.def my_function(i, my_list=[]):
3. my_list.append(i)
4. return my_list
5.>>> my_function(1)
6.[1]
7.>>> my_function(2)
8.[1, 2]
9.>>> my_function(3)
10.[1, 2, 3]
在上面的代码中,每次我们调用 my_function函数时,列表my_list都会不断保存之前调用的值(很可能我们想在每次调用函数时
启动一个空列表)
为了避免这种行为,我们应该将这个 my_list参数设置为None,并加入下面的if子句。
1.# Good
2.def my_function(i, my_list=None):
3. if my_list is None:
4. my_list = []
5. my_list.append(i)
6. return my_list
7.>>> my_function(1)
8.[1]
9.>>> my_function(2)
10.[2]
11.>>> my_function(3)
12.[3]
最后
今天的这篇文章到这里就结束了,喜欢的记得点赞收藏,更多的问题可以评论留言,看就就会回复的哟!!!
【学会轮播图这一篇文章就足够啦】JS 网页轮播图详解 自动播放+手动播放
WSL2中使用Docker基于Centos7.9+宝塔7.9配置的开发环境
pyqt5之TreeWidget中的节点触发弹出界面以及TreeWidget的界面制作------二
Springboot----项目整合微信支付与RabbitMQ(使用RabbitMQ延迟插件实现订单管理)
UI自动化测试:Selenium+PO模式+Pytest+Allure整合
摸了俩小时docker-compose的鱼,Dockerfile常用姿势5分钟速成~