Ethan's Blog


  • Home

  • Archives

  • Tags

  • Search

场景:实现有状态函数

Posted on 2022-03-12

三种实现有状态函数的方式:

  • 基于全局变量:
    • 学习成本低,最容易理解;
    • 会增加模块级的全局状态,封装性和可维护性最差;
  • 基于函数闭包:
    • 学习成本适中,可读性较好;
    • 适合用来实现变量较少、较简单的有状态函数;
  • 创建类来封装状态:
    • 学习成本较高;
    • 当变量较多、行为较复杂时,类代码比闭包代码更易读,也更容易维护;

Ethan 正在自学 Python,一天,他从网上看到一道和字符串处理有关的练习题:

有一段文字,里面包含各类数字,比如数量、价格等,编写一段代码把文字里的所有数字都用星号替代,实现脱敏效果。

使用 re.sub() 函数:

1
2
def mosaic_string(s):
return re.sub(r'\d+', '*', s)
Read more »

函数与装饰器

Posted on 2022-03-12

函数

Python 是一门支持面向对象的编程语言,但除此之外,Python 对函数的支持也毫不逊色。函数在 Python 中是一等对象,这意味着我们可以把函数自身作为函数参数来使用。

函数参数的常用技巧

参数(Parameter)是函数的重要组成部分,它是函数最主要的输入源,决定了调用方使用函数时的体验。Python 函数的参数默认值只会在函数定义阶段被创建一次,别将可变类型作为参数默认值,使用 None 来替代:

1
2
3
def append_value(value, items=[]):
items.append(value)
return items
1
2
3
4
5
6
def append_value(value, items=None):
# 在函数内部进行判断,保证参数默认每次都使用一个新的空列表
if items is None:
items = []
items.append(value)
return items

定义一个特殊对象(标记变量)作为参数默认值,严格区分调用方是不是真的提供了这个默认参数:

1
2
3
4
5
6
# object 通常不会单独使用,但是拿来做这种标记变量刚刚好
_not_set = object()

def dump_value(value, extra=_not_set):
if extra is _not_set:
# TODO: 调用方没有传递 extra 参数
Read more »

场景:数字统计任务

Posted on 2022-03-06

Ethan 是一位 Python 初学者,在学习了如何用 Python 读取文件后,他想要做一个小练习:统计某个文件中数字字符的数量:

1
2
3
4
5
6
7
8
def count_digits(fname):
count = 0
with open(fname) as file:
for line in file:
for s in line:
if s.isdigit():
count += 1
return count

首先用 with open(file_name) 上下文管理器语法获得一个文件对象,然后用 for 循环迭代它,逐行获取文件里的内容。它有两个好处:

  • with 上下文管理器会自动关闭文件描述符;
  • 在迭代文件对象时,内容是一行一行返回的,不会占用太多内存;
Read more »

场景:消除条件分支

Posted on 2022-03-06

使用 bisect 优化范围类分支判断

1
2
3
4
5
6
7
8
9
10
11
12
def rank(rating):
rating_num = float(rating)
if rating_num >= 8.5:
return 'S'
elif rating_num >= 8:
return 'A'
elif rating_num >= 7:
return 'B'
elif rating_num >= 6:
return 'C'
else:
return 'D'

要优化这段代码,我们得把所有分界点收集起来,放在一个元组里。因为 breakpoints 已经是一个排好序的元组,所以我们可以直接使用 bisect 模块来实现查找功能:

1
2
3
4
5
6
7
8
import bisect

def rank(rating):
breakpoints = (6, 7, 8, 8.5)
grades = ('D', 'C', 'B', 'A', 'S')

index = bisect.bisect(breakpoints, float(rating))
return grades[index]
Read more »

语法结构

Posted on 2022-03-05

条件分支控制流

掌握如何写出好的条件分支代码非常重要,它可以帮助我们用更简洁、更清晰的代码来表达复杂逻辑。

分支惯用写法

当某个对象作为主角出现在 if 分支里时,解释器会主动对它进行真值测试,也就是调用 bool() 函数获取它的布尔值:

1
2
>>> bool([]), bool([1, 2, 3])
(False, True)

不要因为过度追求简写而引入其他逻辑问题:

1
2
3
4
5
6
7
# 更精准:只有为 0 的时候,才会满足分支条件
if containers_count == 0:
pass

# 更宽泛:为 0、None、空字符串等时,都可以满足分支条件
if not containers_count:
pass
Read more »
1…121314…55
necusjz

necusjz

274 posts
16 tags
© 2016 - 2025 necusjz
Powered by Hexo
Theme - NexT.Mist