Python 二十三大实践、编码建议和技巧

简介: Python 二十三大实践、编码建议和技巧


一、开篇



你又立了什么新的 Flag?新一年,我为大家准备 23 个非常优秀的 Python 实践技巧。希望这些诀窍能在实际工作中帮助大家,并且学到一些有用的知识。



二、技巧篇



1、检查并使用满足需求的最小Python版本 

你可以在代码中检查Python 版本,以确保你的代码使用者没有使用不兼容的版本运行脚本。使用以下代码进行简单的检查:

import sys
if not sys.version_info > (2, 7):
    print('当前Python版本低于2.7')
elif (2, 7) <= sys.version_info <= (3, 8):
    print('当前Python版本大于或等于2.7但小于3.8')
else:
    print('其它版本')



2、列表解析式

列表解析式可以用来替换通过循环来填充列表的丑陋方法,其基本语法是:


[ expression for item in list if conditional ]

一个非常基础的例子,用于生成包含连续数字的列表:

mylist = [i for i in range(10)]
print(mylist)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]



由于可以使用表达式,因此可以通过更复杂的数学方法来生成列表:

squares = [x**2 for x in range(10)]
print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]


甚至也可以调用外部函数:

def some_function(a):
    return (a + 5) / 2
my_function = [some_function(i) for i in range(10)]
print(my_function)
# [2, 3, 3, 4, 4, 5, 5, 6, 6, 7]



最后,也可以用if作为生成条件来对列表进行过滤。在下面的例子中,只有偶数被保留

filtered = [i for i in range(20) if i%2==0]
print(filtered)
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]



3、检查对象的内存占用情况

 通过sys.getsizeof(object)命令可以查看任何对象的内存使用情况

import sys
mylist=range(0, 1000000)
print(sys.getsizeof(mylist))



因为range函数返回的是一个类对象,这个类对象表现为一个列表。因此使用range函数比使用实际的包含一万个数字的列表要更加节省内存。



4、'==' VS 'is'用法

等于(==)和 is 是 Python 中对象比较常用的两种方式。简单来说,'=='操作符比较对象之间的值是否相等,比如下面的例子,表示比较变量 a 和 b 所指向的值是否相等。


a == b

而'is'操作符比较的是对象的身份标识是否相等,即它们是否是同一个对象,是否指向同一个内存地址。在 Python 中,每个对象的身份标识,都能通过函数 id(object) 获得。因此,'is'操作符,相当于比较对象之间的 ID 是否相等。

a = 10
b = 10
a == b
True
id(a)
4427562448
id(b)
4427562448
a is b
True


不过,需要注意,对于整型数字来说,以上a is b为 True 的结论,只适用于 -5 到 256 范围内的数字。比如下面这个例子:

a = 257
b = 257
a == b
True
id(a)
4473417552
id(b)
4473417584
a is b
False

这里我们把 257 同时赋值给了 a 和 b,可以看到a == b仍然返回 True,因为 a 和 b 指向的值相等。但奇怪的是,a is b返回了 false,并且我们发现,a 和 b 的 ID 不一样了,这是为什么呢?


这是由于Python出于对性能优化的考虑,Python 内部会对 -5 到 256 的整型维持一个数组,起到一个缓存的作用。这样,每次你试图创建一个 -5 到 256 范围内的整型数字时,Python 都会从这个数组中返回相对应的引用,而不是重新开辟一块新的内存空间。但是,如果整型数字超过了这个范围,比如上述例子中的 257,Python 则会为两个 257 开辟两块内存区域,因此 a 和 b 的 ID 不一样,a is b就会返回 False 了。


通常来说,在实际工作中,当我们比较变量时,使用'=='的次数会比'is'多得多,因为我们一般更关心两个变量的值,而不是它们内部的存储地址。但是,当我们比较一个变量与一个单例(singleton)时,通常会使用'is'。


5、返回多个值

Pyhon中的函数都可以返回多个变量,而不需要字典,列表或者类作为返回对象。方法如下:

def get_user(id):
    # fetch user from database
    # ....
    return name, birthdate
name, birthdate = get_user(4)


对于有限数量的返回值,这是可以的。但是任何超过3个值的内容都应该放到一个(data)类中。


6、使用 data 类

从3.7版本开始,Python提供了 data 类。与常规类或其他替代方法(如返回多个值或字典)相比,有以下几个优点:


  • 数据类需要至少一定数量的代码
  • 可以通过 __eq__ 方法来比较不同的data类对象
  • 可以 __repr__ 通过很容易地打印一个数据类来进行调试
  • 数据类需要类型提示,因此减少了 bug


一个data类的例子如下:

from dataclasses import dataclass
@dataclass
class Card:
    name: str
    sex: str
card = Card("MikeZhou", "Man")
print(card.name)
# 'Mikezhou'
print(card.sex)
# 'Man'
print(card)


详细教程参见:https://realpython.com/python-data-classes/


7、字典合并(Python 3.5+)从Python 3.5开始,字典的合并变得更简单了:

dict1 = { 'a': 1, 'b': 2 }
dict2 = { 'b': 3, 'c': 4 }
merged = { **dict1, **dict2 }
print (merged)
# {'a': 1, 'b': 3, 'c': 4}



8、将字符串转化为标题格式

在标题格式中,非介词的首字母会大写。可以通过.title()方法实现:

mystring = "awesome python tricks"
print(mystring.title())
'Awesome Python Tricks'


9、将列表中的字符串合并到一起

从列表中创建字符串,并在两个单词间插入空格:

mylist = ['mikezhou_talk', '中文名是:', '测试开发技术']
mystring = " ".join(mylist)
print(mystring)
# 'mikezhou_talk 中文名是: 测试开发技术'


也许你会疑惑,为什么不使用mylist.join(" ")呢?归根结底,String.join()函数不仅可以连接列表,还可以连接任何可迭代的列表。将它放在String中会阻止在多个位置实现相同的功能。


10、Emoji表情

微信图片_20220524100939.png


这些表情具有很强的表达能力,能给人留下深刻印象。更重要的是,这在分析社交媒体数据时尤其有用。 首先通过以下命令安装emoji模块:


pip3 install emoji


可以按照以下方法使用表情:

import emoji
result = emoji.emojize('Python is :thumbs_up:')
print(result)
# 'Python is 👍'
# You can also reverse this:
result = emoji.demojize('Python is 👍')
print(result)
# 'Python is :thumbs_up:'


更多复杂的例子以及文档,参见:https://pypi.org/project/emoji/

11、翻转字符串和列表

可以用切片操作来翻转列表或字符串,将step设置为负值即可实现:

revstring = "abcdefg"[::-1]
print(revstring)
# 'gfedcba'
revarray = [1, 2, 3, 4, 5][::-1]
print(revarray)
# [5, 4, 3, 2, 1]



12、图片显示

可以通过Pillow模块来显示图片,首先安装python图片库:


pip3 install Pillow


然后下载你要显示的图片,并重命名。然后可以通过以下命令来显示图片:

from PIL import Image
im = Image.open("mikezhou.jpg")
im.show()
print(im.format, im.size, im.mode)
# JPEG (1920, 1357) RGB


Pillow的功能远不止显示图片。它可以对图片进行分析,调整大小,滤波,增强,变形等等。更多资料详见文档:https://pillow.readthedocs.io/en/stable/


13、从列表或字符串中获取唯一元素

通过set()函数可以将列表或字符串转换为集合,集合中的不含重复元素:

mylist = [1, 1, 2, 3, 4, 5, 5, 5, 6, 6]
print (set(mylist))
# {1, 2, 3, 4, 5, 6}
print (set("aaabbbcccdddeeefff"))
# {'a', 'b', 'c', 'd', 'e', 'f'}

14、找出最常出现的值

查找列表或字符串中最常出现的值:

test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4]
print(max(set(test), key = test.count))
# 4


你可以尝试自行理解上述代码。好吧,也许你并没有尝试。上述代码的工作原理如下:

  • max()将返回列表中的最大值。key参数接受单个参数函数确定定制排序顺序,在本例中,它是test.count,该函数应用于iterable对象中的每个元素。
  • .count()是列表的一个内建函数,该函数接收一个参数,并计算该参数的出现次数。因此在本例中,test.count(1)返回2,testcount(4)返回4。
  • set(test)返回test列表中的所有唯一值,因此是{1,2,3,4}。

 因此在上面的这行语句中我们首先找出了test列表的所有独特值,即{1,2,3,4}。接着,将.count函数应用于set中的每个值,得到一个数量列表,然后通过max找出数量最大的值。


15、创建进度条

可以自行创建进度条,但也可以通过progress模块来快速创建:


pip3 install progress


然后通过以下代码来创建进度条:

from progress.bar import Bar
bar = Bar('Processing', max=20)
for i in range(20):
    # Do some work
    bar.next()
bar.finish()



16、快速创建web服务器

您可以快速启动web服务器,来提供当前工作目录的内容:


python3 -m http.server

如果您想与同事共享一些内容,或者想测试一个简单的HTML站点,这是非常有用的。


17、用于条件赋值的三元运算符


这是另一种使你代码变得简洁,同时保持可读性的方法:


[on_true] if [expression] else [on_false]

一个简单的例子如下:


x = "Success!" if (y == 2) else "Failed!"


18、统计元素的出现次数可以使用Collections依赖包中的Counter方法来获得一个包含列表中所有惟一元素计数的字典:

from collections import Counter
mylist = [1, 1, 2, 3, 4, 5, 5, 5, 6, 6]
c = Counter(mylist)
print(c)
# Counter({1: 2, 2: 1, 3: 1, 4: 1, 5: 3, 6: 2})
print(Counter("aaaaabbbbbccccc"))
# Counter({'a': 5, 'b': 5, 'c': 5})



19、加入色彩


微信图片_20220524101356.png


通过 Colorama 依赖包,可以在终端中添加更多色彩:

from colorama import Fore, Back, Style
print(Fore.RED + 'some red text')
print(Back.GREEN + 'and with a green background')
print(Style.DIM + 'and in dim text')
print(Style.RESET_ALL)
print('back to normal now')


关于Colorama依赖包的更多信息,参见:https://pypi.org/project/colorama/


20、日期处理

python-dateutil模块为标准的datetime模块提供了强大的扩展。首先安装该模块:


pip3 install python-dateutil

你可以用这个库做很多很酷的事情。我讲把我认为特别有用的一个功能作为示例:日志文件中日期的模糊解析等。如下:

from dateutil.parser import parse
logline = 'INFO 2020-01-01T00:00:01 Happy new year, human.'
timestamp = parse(log_line, fuzzy=True)
print(timestamp)
# 2020-01-01 00:00:01


只要记住,如果datatime不具备某个功能,那datautil一定有该功能,datautil是datatime功能的延续。


21、通过chardet检测字符集合

可以使用chardet模块来检测文件中的字符集合。这在分析大量随机文本时非常有用。安装chardet模块:


pip install chardet


现在你有了一个额外的命令行工具chardetect,它可以这样使用:

chardetect somefile.txt
somefile.txt: ascii with confidence 1.0


你也可以通过编程的方式来使用这个依赖包,详见文档:https://chardet.readthedocs.io/en/latest/usage.html 

22、用 cProfile 进行性能分析

日常工作中,我们常常会遇到这样的问题:在线上,产品的某个功能模块效率低下,延迟(latency)高,占用的资源多,但却不知道是哪里出了问题。如果能对代码的每个部分进行动态的分析,比如准确计算出每个模块消耗的时间等。这样就可以知道程序的瓶颈所在,从而对其进行修正或优化。在 Python 中,这些需求用 cProfile 就可以实现。举个例子,比如我想计算斐波拉契数列,运用递归思想,我们很容易就能写出下面这样的代码:

def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)
def fib_seq(n):
    res = []
    if n > 0:
        res.extend(fib_seq(n-1))
    res.append(fib(n))
    return res
fib_seq(30)


接下来,我想要测试一下这段代码总的效率以及各个部分的效率。那么,我就只需在开头导入 cProfile 这个模块,并且在最后运行 cProfile.run() 就可以了:

import cProfile
# def fib(n)
# def fib_seq(n):
cProfile.run('fib_seq(30)')


或者更简单一些,直接在运行脚本的命令中,加入选项“-m cProfile”也很方便:


python3 -m cProfile xxx.py

运行完毕后,我们可以看到下面这个输出界面:微信图片_20220524101639.png

23、合理利用assert

Python 的 assert 语句,可以说是一个 debug 的好工具,主要用于测试一个条件是否满足。如果测试的条件满足,则什么也不做,相当于执行了 pass 语句;如果测试条件不满足,便会抛出异常 AssertionError,并返回具体的错误信息。

比如下面这个例子:


assert 1 == 2,  'assertion is wrong'

它相当于下面这两行代码:

if __debug__:
    if not expression1: raise AssertionError(expression2)

这里的__debug__是一个常数。如果 Python 程序执行时附带了-O这个选项,比如Python test.py -O,那么程序中所有的 assert 语句都会失效,常数__debug__便为 False;反之__debug__则为 True。
再来看一个例子:

def apply_discount(price, discount):
    updated_price = price * (1 - discount)
    assert 0 <= updated_price <= price, 'price should be greater or equal to 0 and less or equal to original price'
    return updated_price


我们加入了 assert 语句,规定销售数目必须大于 0,这样就可以防止后台计算那些还未开卖的课程的价格。


总的来说,assert 在程序中的作用,是对代码做一些 internal 的 self-check。使用 assert,就表示你很确定。这个条件一定会发生或者一定不会发生。如果你的程序没有 bug,那么 assert 永远不会抛出异常;而它一旦抛出了异常,你就知道程序存在问题了,并且可以根据错误信息,很容易定位出错误的源头。




以上就是为大家整理的23个Python常用技巧,希望这些技巧能帮助你在新的一年里有个不错的开始。


无论是对于 Python 这门语言,还是其他语言,或是计算机的其他领域,我认为实践永远是至关重要的。计算机科学是一门偏向工程的学科,所以一定要多实践,多写代码,多交流,多思考


希望这篇文章能帮到你!更多干货文章请关注我们。


目录
相关文章
|
30天前
|
机器学习/深度学习 算法 搜索推荐
从理论到实践,Python算法复杂度分析一站式教程,助你轻松驾驭大数据挑战!
【10月更文挑战第4天】在大数据时代,算法效率至关重要。本文从理论入手,介绍时间复杂度和空间复杂度两个核心概念,并通过冒泡排序和快速排序的Python实现详细分析其复杂度。冒泡排序的时间复杂度为O(n^2),空间复杂度为O(1);快速排序平均时间复杂度为O(n log n),空间复杂度为O(log n)。文章还介绍了算法选择、分而治之及空间换时间等优化策略,帮助你在大数据挑战中游刃有余。
53 4
|
26天前
|
存储 程序员 开发者
Python编程基础:从入门到实践
【10月更文挑战第8天】在本文中,我们将一起探索Python编程的奇妙世界。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供有价值的信息。我们将从Python的基本概念开始,然后逐步深入到更复杂的主题,如数据结构、函数和类。最后,我们将通过一些实际的代码示例来巩固我们的知识。让我们一起开始这段Python编程之旅吧!
|
1月前
|
缓存 开发者 Python
探索Python中的装饰器:从入门到实践
【9月更文挑战第36天】装饰器,在Python中是一种特殊的语法糖,它允许你在不修改原有函数代码的情况下,增加额外的功能。本文将通过浅显易懂的语言和实际代码示例,带你了解装饰器的基本原理,探索其背后的魔法,并展示如何在实际项目中运用这一强大工具。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往更高效、更优雅代码的大门。
56 11
|
2天前
|
Python
探索Python装饰器:从入门到实践
【10月更文挑战第32天】在编程世界中,装饰器是一种特殊的函数,它允许我们在不改变原有函数代码的情况下,增加额外的功能。本文将通过简单易懂的语言和实际案例,带你了解Python中装饰器的基础知识、应用以及如何自定义装饰器,让你的代码更加灵活和强大。
9 2
|
2天前
|
监控 Python
探索Python中的装饰器:从入门到实践
【10月更文挑战第31天】在Python的世界里,装饰器是那些隐藏在幕后的魔法师,它们拥有着改变函数行为的能力。本文将带你走进装饰器的世界,从基础概念到实际应用,一步步揭开它的神秘面纱。你将学会如何用几行代码增强你的函数功能,以及如何避免常见的陷阱。让我们一起来发现装饰器的魔力吧!
|
2天前
|
开发框架 开发者 Python
探索Python中的装饰器:技术感悟与实践
【10月更文挑战第31天】 在编程世界中,装饰器是Python中一种强大的工具,它允许我们在不修改函数代码的情况下增强函数的功能。本文将通过浅显易懂的方式,带你了解装饰器的概念、实现原理及其在实际开发中的应用。我们将一起探索如何利用装饰器简化代码、提高可读性和复用性,同时也会分享一些个人的技术感悟,帮助你更好地掌握这项技术。
11 2
|
5天前
|
数据管理 程序员 数据处理
利用Python自动化办公:从基础到实践####
本文深入探讨了如何运用Python脚本实现办公自动化,通过具体案例展示了从数据处理、文件管理到邮件发送等常见办公任务的自动化流程。旨在为非程序员提供一份简明扼要的实践指南,帮助他们理解并应用Python在提高工作效率方面的潜力。 ####
|
5天前
|
数据采集 存储 XML
Python实现网络爬虫自动化:从基础到实践
本文将介绍如何使用Python编写网络爬虫,从最基础的请求与解析,到自动化爬取并处理复杂数据。我们将通过实例展示如何抓取网页内容、解析数据、处理图片文件等常用爬虫任务。
|
12天前
|
数据可视化 数据挖掘 Python
使用Python进行数据可视化:探索与实践
【10月更文挑战第21天】本文旨在通过Python编程,介绍如何利用数据可视化技术来揭示数据背后的信息和趋势。我们将从基础的图表创建开始,逐步深入到高级可视化技巧,包括交互式图表和动态展示。文章将引导读者理解不同图表类型适用的场景,并教授如何使用流行的库如Matplotlib和Seaborn来制作美观且具有洞察力的可视化作品。
39 7
|
10天前
|
测试技术 开发者 Python
探索Python中的装饰器:从入门到实践
【10月更文挑战第24天】 在Python的世界里,装饰器是一个既神秘又强大的工具。它们就像是程序的“隐形斗篷”,能在不改变原有代码结构的情况下,增加新的功能。本篇文章将带你走进装饰器的世界,从基础概念出发,通过实际例子,逐步深入到装饰器的高级应用,让你的代码更加优雅和高效。无论你是初学者还是有一定经验的开发者,这篇文章都将为你打开一扇通往高效编程的大门。