当前位置:首页>python>从“会用”到“会写”——Python进阶之路:那些让你写出优雅代码的特性

从“会用”到“会写”——Python进阶之路:那些让你写出优雅代码的特性

  • 2026-10-09 03:22:08
从“会用”到“会写”——Python进阶之路:那些让你写出优雅代码的特性
你好呀,我是小冰。

之前写了Python的基础语法和循环语句,有读者说:“基础的我都练了,但写稍微复杂一点的程序,感觉代码还是一团乱麻。怎么才能写出‘像样’的代码?”

这个问题问到点子上了。

会用变量、循环、判断,就像是学会了造砖头。但要盖一座能住人的房子,你还需要知道怎么砌墙、怎么搭梁、怎么布线。

今天这篇,就聊聊Python里那些“让代码从能跑变成好看”的进阶特性。不是让你成为专家,而是让你在写科研代码时,能少掉点头发。


一、函数进阶:让代码“像积木一样拼”

上篇我们讲了函数的基本写法。今天再深入一点,看看函数还能怎么玩。

1.1 参数的花式玩法

默认参数——给参数一个“保底值”

python

def greet(name, greeting="你好"):
    return f"{greeting},{name}"
print(greet("小冰"))# 你好,小冰
print(greet("小冰","早上好"))# 早上好,小冰

科研场景:处理实验数据时,校准系数可能经常不变,就可以设默认值。

python

def calibrate(data, coeff=1.02):
    return[x * coeff for x in data]
# 大部分时候用默认校准
normal_data = calibrate(raw_data)
# 偶尔需要特殊校准
special_data = calibrate(raw_data, coeff=1.05)

可变参数——不知道传多少个参数时用*args

python

def sum_all(*numbers):
    return sum(numbers)
print(sum_all(1,2,3,4,5))# 15

关键字参数——用**kwargs接收键值对

python

def record_exp(**info):
    for key, value in info.items():
print(f"{key}: {value}")
record_exp(name="温度实验", date="2024-06-01", temp=298.15)
# name: 温度实验
# date: 2024-06-01
# temp: 298.15

1.2 lambda表达式:一句话写完的函数

有时候函数太简单,连def都不想写,就可以用lambda。

python

# 普通函数
def square(x):
    return x **2
# lambda写法
square =lambda x: x **2

最常用在需要“临时函数”的地方,比如排序。

python

students =[
    {"name":"张三","score":85},
    {"name":"李四","score":92},
    {"name":"王五","score":78}
]
# 按分数排序
students.sort(key=lambda s: s["score"], reverse=True)

1.3 函数作为参数:高阶函数

Python可以把函数当成普通变量传来传去。

python

def apply(func, data):
    return[func(x) for x in data]
def square(x):
    return x **2
def cube(x):
    return x **3
numbers =[1,2,3,4]
print(apply(square, numbers))# [1, 4, 9, 16]
print(apply(cube, numbers))# [1, 8, 27, 64]

这在数据处理中特别有用——你可以写一个通用的“处理流程”,具体怎么处理,通过传不同的函数来决定。


二、模块与包:把代码“装进抽屉”

写代码就像整理实验室。如果一个实验台上堆满东西,你什么都找不到。但如果每个抽屉里分类放好,就方便多了。

模块,就是Python里的“抽屉”。

2.1 导入模块

python

# 导入整个模块
import math 
print(math.sqrt(16))# 4.0
# 导入特定函数
from math import pi, sin
print(pi)# 3.14159...
# 导入并起别名(常用)
import numpy as np

2.2 自定义模块

把你写好的函数保存到一个.py文件中,比如my_tools.py:

python

# my_tools.py
def calculate_bmi(weight, height):
    return weight /(height **2)
def get_category(bmi):
    if bmi <18.5:
        return"偏瘦"# ... 省略

然后在另一个文件里:

python

import my_toolsbmi = my_tools
calculate_bmi(70,1.75)
print(my_tools.get_category(bmi))

2.3 if __name__ == "__main__" 的妙用

很多Python文件末尾都会有这段代码:

python

def main():# 这里是主程序逻辑
    pass
if __name__ =="__main__":
    main()

它的作用是:当这个文件被直接运行时,执行main();当这个文件被别的文件导入时,不执行main()。

这样,一个文件既可以作为工具库被别人用,也可以独立运行。


三、文件操作:让程序“记住”数据

实验数据不能每次都手动输入,得学会读写文件。

3.1 读文本文件

python

# 推荐使用 with,自动关闭文件
with open("data.txt","r", encoding="utf-8")as f:
    content = f.read()# 全部读出来
    # 或者一行一行读
    for line in f:
        print(line.strip())# strip去掉换行符

3.2 写文本文件

python

data =["实验1: 23.5","实验2: 24.1","实验3: 22.8"]
with open("result.txt","w", encoding="utf-8")as f:
    for line in data:
        f.write(line +"\n")# 手动加换行

"w"是覆盖写入,"a"是追加写入。

3.3 科研常用的:读取CSV文件

CSV(逗号分隔值)是实验数据最常用的格式之一。

python

import csv 
with open("experiment.csv","r", encoding="utf-8")as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)# row是一个列表,每个元素是一列

如果第一行是表头,可以用csv.DictReader直接得到字典:

python

with open("experiment.csv","r")as f:
    reader = csv.DictReader(f)
    for row in reader:
        print(row["温度"], row["压力"])

四、异常处理:让程序“摔倒了能爬起来”

写代码最怕的是,一运行就报错,程序直接崩了。

用异常处理,可以优雅地处理错误。

4.1 基本用法

python

try:
    num =int(input("请输入一个整数:"))
    result =10/ num
    print(f"结果是:{result}")
except ValueError:
    print("输入的不是整数!")
except ZeroDivisionError:
    print("不能除以0!")
except Exception as e:
    print(f"其他错误:{e}")
else:
    print("没有发生异常,一切正常")
finally:
    print("无论如何都会执行的代码")

科研场景:读取可能不存在的文件

python

filename ="data.csv"
try:
    with open(filename,"r")as f:
        data = f.read()
except FileNotFoundError:
    print(f"文件{filename}不存在,使用默认数据")
    data ="默认数据"

4.2 主动抛出异常

有时候发现数据有问题,想主动报错:

python

def check_temperature(temp):
    if temp <-273.15:
        raise ValueError(f"温度{temp}低于绝对零度!")
    return temp
check_temperature(-300)# 会抛出异常

五、面向对象编程:让代码“更像现实世界”

面向对象是Python的核心特性,简单说就是把数据和操作数据的方法打包在一起。

5.1 一个简单的类

python

class Experiment:"""实验记录类"""
    def__init__(self, name, date):
        self.name = name
# 属性
        self.date = date
        self.results =[]
    # 初始为空列表
    def add_result(self, value):
        """添加实验结果"""
        self.results.append(value)
        print(f"已添加结果:{value}")
    def get_average(self):
        """计算平均值"""
        if self.results:
            return sum(self.results)/len(self.results)
        else:
            return0
    def report(self):
        """输出报告"""
        print(f"实验:{self.name}")
        print(f"日期:{self.date}")
        print(f"结果:{self.results}")
        print(f"平均值:{self.get_average():.2f}")

使用:

python

exp = Experiment("飞轮储能测试","2024-06-01")
exp.add_result(23.5)
exp.add_result(24.1)
exp.add_result(22.8)
exp.report()

输出:

text

实验:飞轮储能测试
日期:2024-06-01
结果:[23.5, 24.1, 22.8]
平均值:23.47

5.2 为什么用类?

  • 封装:把相关的数据和函数放在一起,代码更清晰

  • 复用:可以基于一个类创建多个实例(多个实验)

  • 扩展:可以通过继承增加新功能


六、生成器与迭代器:处理大数据时的“省内存神器”

如果你的数据很大(比如几百万行实验记录),一次性读进内存可能直接卡死。

生成器可以“按需生成”,用一点吐一点。

6.1 用yield创建生成器

python

def read_large_file(filename):
    """逐行读取大文件,不一次性加载到内存"""
    with open(filename,"r") as f:
        for line in f:
            yield line.strip()# 每次yield一行,然后暂停
# 使用
for line in read_large_file("big_data.csv"):
    process(line)# 处理一行,内存里永远只有一行

6.2 生成器表达式

类似列表推导式,但用()而不是[],不会立即生成所有元素。

python

# 列表推导式:立即生成全部,占用内存
squares_list =[x**2for x inrange(10000000)]
# 可能卡死# 生成器表达式:按需生成,内存友好
squares_gen =(x**2 for x in range(10000000))for s in squares_gen:
if s >1000:
        break# 只需要前面的,后面的根本不计算

写在最后

今天这篇内容有点多,但都是你写出“优雅、健壮、可维护”代码的必备武器。

总结一下:

  • 函数进阶让代码可复用

  • 模块让代码可管理

  • 文件操作让数据可持久

  • 异常处理让程序可容错

  • 面向对象让逻辑可组织

  • 生成器让内存可节省

不需要一次性全记住,但遇到问题的时候,知道“哦,Python有这个工具,我去查一下”就够了。

如果你正在学Python,遇到了什么卡点,欢迎在评论区告诉我。我们一起踩坑,一起进步。

最新文章

随机文章