
写 Python 函数时,你是不是总被各种问题困扰?函数没写完却没提示,调用时出问题找不到原因;团队协作时,不知道函数返回啥类型,老是出类型错误;想理解个复杂函数,得一行行看代码,费时又费力…… 别愁,5 个技巧帮你搞定,写出专业的 Python 代码!
平时写函数,没写完的时候是不是习惯用 pass 占个位?但这样可不好,要是不小心调用了这个没写完的函数,它不声不响的,出了问题都不知道在哪。这时候就得用 NotImplementedError 了。
比如用 pass 的情况:
def calculate_average(numbers):
# 还没写完
pass
# 不小心调用了
calculate_average([1,2,3]) # 啥反应没有,出问题不好找换成 NotImplementedError 就不一样了:
def calculate_average(numbers):
# 还没写完,抛出错误并提示
raise NotImplementedError("这个函数还没实现,正在开发中")
# 调用的话
calculate_average([1,2,3]) # 直接报错,告诉你哪有问题面试官可能会问:“在未完成的函数中,用 pass 和 NotImplementedError 有什么区别?”
回答:pass 会让函数静默执行,不产生任何提示,当不小心调用时,出了问题很难排查;而 NotImplementedError 会直接抛出错误,并可以添加提示信息,能快速定位到未完成的函数,适合标记未完成的函数,在大型项目调试中更高效。
在函数签名中添加类型注解,好处可不少。IDE 能实时检查类型错误,团队协作时,别人一看就知道函数返回值的结构,能减少数据类型不匹配的 bug。
比如这样给函数加返回类型注解:
def get_users() -> dict[int, str]:
return {1: "张三", 2: "李四"}
def add_numbers(a: int, b: int) -> int:
return a + b当你在 IDE 中调用这些函数时,如果对返回值进行不符合类型的操作,IDE 就会提示错误。比如:
users = get_users()
print(users + 1) # IDE会提示错误,因为dict不能和int相加函数声明 | 实际返回值 | 可能导致的问题 |
|---|---|---|
def func() -> int | return "123" | 调用时用返回值进行数值运算会出错 |
def func() -> list | return {"a": 1} | 调用时用列表的方法操作返回值会出错 |
面试官可能会问:“Python 函数中添加返回类型注解有什么作用?”
回答:添加返回类型注解可以让 IDE 实时检查类型错误,帮助开发者在编写代码时及时发现问题;让其他开发者在调用函数时,一目了然地知道返回值的结构和类型,减少数据类型不匹配的 bug,提高团队协作的效率。
用三引号注释说明函数功能、参数、返回值,配合 Sphinx 等工具还能生成文档。即使是复杂函数,通过悬停查看注释就能快速理解用途,比读代码逻辑更直接,是代码自文档化的必备技巧。
比如一个有详细文档字符串的函数:
def calculate_area(length: float, width: float) -> float:
"""
计算长方形的面积
参数:
length: 长方形的长度,必须是正数
width: 长方形的宽度,必须是正数
返回值:
float: 长方形的面积,即长度乘以宽度
示例:
>>> calculate_area(3, 4)
12.0
"""
if length <= 0 or width <= 0:
raise ValueError("长度和宽度必须是正数")
return length * width在 IDE 中,当你悬停在调用这个函数的地方,就能看到这些注释信息,快速了解函数的用法。
面试官可能会问:“如何让 Python 函数更易被他人理解?”
回答:可以给函数添加详细的文档字符串,用三引号注释说明函数的功能、参数的含义和要求、返回值的类型和意义,还可以加上示例。这样别人不用阅读函数内部的代码逻辑,通过查看文档字符串就能快速理解函数的用法。
在函数签名中使用 * 分隔位置参数和关键字参数,调用时必须显式传入参数名,能避免因参数顺序错误导致的逻辑问题,让复杂函数调用更清晰。
比如这样定义函数:
def upload(file: str, *, quality: str, privacy: bool):
print(f"上传文件: {file},质量: {quality},是否私密: {privacy}")调用这个函数时,必须显式传入 quality 和 privacy 的参数名:
upload("test.txt", quality="high", privacy=True) # 正确
# upload("test.txt", "high", True) # 错误,会抛出TypeError面试官可能会问:“在定义函数时,如何避免调用者因参数顺序错误而导致问题?”
回答:可以在函数签名中使用 * 来分隔位置参数和关键字参数,将一些容易混淆顺序的参数设为强制关键字参数。这样调用者在调用函数时必须显式传入这些参数的名称,从而避免因参数顺序错误导致的逻辑问题。
通过 def join_text (*strings, separator) 接收任意数量位置参数,轻松处理动态输入(如拼接多个字符串),让函数灵活性飙升,告别参数数量限制烦恼。
比如这个拼接字符串的函数:
def join_text(*strings, separator: str = " "):
"""
拼接多个字符串
参数:
*strings: 要拼接的多个字符串
separator: 分隔符,默认为空格
返回值:
str: 拼接后的字符串
"""
return separator.join(strings)
# 调用示例
print(join_text("Hello", "world", "!", separator="-")) # 输出:Hello-world-!
print(join_text("Python", "is", "great")) # 输出:Python is great面试官可能会问:“*args 的作用是什么,在什么情况下使用?”
回答:args 用于在函数定义中接收任意数量的位置参数,这些参数会被打包成一个元组在函数内部使用。当函数需要处理动态数量的输入,比如拼接多个字符串、计算多个数的和等情况时,可以使用args,它能增加函数的灵活性,摆脱参数数量的限制。
从错误处理到参数设计,这 5 个技巧针对日常编码中的痛点,能帮助你写出更专业的函数。无论是新手理清逻辑,还是老手优化代码,都能提升开发效率。赶紧把这些技巧用起来,让你的 Python 代码更上一层楼吧!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。