Python 工匠:让函数返回结果的技巧

Python惯例 Python惯例 “惯例”这个词指的是“习惯的做法,常规的办法,一贯的做法”,与这个词对应的英文单词叫“idiom”。由于Python跟其他很多编程语言在语法和使用上还是有比较显著的差别,因此作为一个Python开发者如果不能掌握这些惯例,就无法写出“Pythonic”的代码。下面我们总结了一些在Python开发中的惯用的代码。 让代码既可以被导入又可以被执行。 if __name__ ==... 阅读详情

毫无疑问,函数是 Python 语言里最重要的概念之一。在编程时,我们将真实世界里的大问题分解为小问题,然后通过一个个函数交出答案。函数即是重复代码的克星,也是对抗代码复杂度的最佳武器。

如同大部分故事都会有结局,绝大多数函数也都是以返回结果作为结束。函数返回结果的手法,决定了调用它时的体验。所以,了解如何优雅的让函数返回结果,是编写好函数的必备知识。

Python 的函数返回方式

Python 函数通过调用 return 语句来返回结果。使用 returnvalue 可以返回单个值,用 returnvalue1,value2 则能让函数同时返回多个值。

如果一个函数体内没有任何 return 语句,那么这个函数的返回值默认为 None。除了通过 return 语句返回内容,在函数内还可以使用抛出异常(raise Exception)的方式来“返回结果”。

接下来,我将列举一些与函数返回相关的常用编程建议。

编程建议

1. 单个函数不要返回多种类型

Python 语言非常灵活,我们能用它轻松完成一些在其他语言里很难做到的事情。比如:让一个函数同时返回不同类型的结果。从而实现一种看起来非常实用的“多功能函数”。

就像下面这样:

def get_users(user_id=None):
    if user_id is None:
        return User.get(user_id)
    else:
        return User.filter(is_active=True)
# 返回单个用户
get_users(user_id=1)
# 返回多个用户
get_users()

当我们需要获取单个用户时,就传递 user_id 参数,否则就不传参数拿到所有活跃用户列表。一切都由一个函数 get_users 来搞定。这样的设计似乎很合理。

然而在函数的世界里,以编写具备“多功能”的瑞士军刀型函数为荣不是一件好事。这是因为好的函数一定是 “单一职责(Single responsibility)” 的。单一职责意味着一个函数只做好一件事,目的明确。这样的函数也更不容易在未来因为需求变更而被修改。

而返回多种类型的函数一定是违反“单一职责”原则的,好的函数应该总是提供稳定的返回值,把调用方的处理成本降到最低。像上面的例子,我们应该编写两个独立的函数 get_user_by_id(user_id)、 get_active_users()来替代。

2. 使用 partial 构造新函数

假设这么一个场景,在你的代码里有一个参数很多的函数 A,适用性很强。而另一个函数 B 则是完全通过调用 A 来完成工作,是一种类似快捷方式的存在。

比方在这个例子里, double 函数就是完全通过 multiply 来完成计算的:

def multiply(x, y):
    return x * y
def double(value):
    # 返回另一个函数调用结果
    return multiply(2, value)

对于上面这种场景,我们可以使用 functools 模块里的 partial() 函数来简化它。

partial(func,*args,**kwargs) 基于传入的函数与可变(位置/关键字)参数来构造一个新函数。所有对新函数的调用,都会在合并了当前调用参数与构造参数后,代理给原始函数处理。

利用 partial 函数,上面的 double 函数定义可以被修改为单行表达式,更简洁也更直接。

import functools
double = functools.partial(multiply, 2)

建议阅读:partial 函数官方文档

3. 抛出异常,而不是返回结果与错误

我在前面提过,Python 里的函数可以返回多个值。基于这个能力,我们可以编写一类特殊的函数:同时返回结果与错误信息的函数。

def create_item(name):
    if len(name) > MAX_LENGTH_OF_NAME:
        return None, 'name of item is too long'
    if len(CURRENT_ITEMS) > MAX_ITEMS_QUOTA:
        return None, 'items is full'
    return Item(name=name), ''
def create_from_input():
    name = input()
    item, err_msg = create_item(name)
    if err_msg:
        print(f'create item failed: {err_msg}')
    else:
        print(f'item<{name}> created')

在示例中, create_item 函数的作用是创建新的 Item 对象。同时,为了在出错时给调用方提供错误详情,它利用了多返回值特性,把错误信息作为第二个结果返回。

乍看上去,这样的做法很自然。尤其是对那些有 Go 语言编程经验的人来说更是如此。但是在 Python 世界里,这并非解决此类问题的最佳办法。因为这种做法会增加调用方进行错误处理的成本,尤其是当很多函数都遵循这个规范而且存在多层调用时。

Python 具备完善的异常(Exception)机制,并且在某种程度上鼓励我们使用异常(官方文档关于 EAFP 的说明)。所以,使用异常来进行错误流程处理才是更地道的做法。

引入自定义异常后,上面的代码可以被改写成这样:

class CreateItemError(Exception):
    """创建 Item 失败时抛出的异常"""
def create_item(name):
    """创建一个新的 Item
    :raises: 当无法创建时抛出 CreateItemError
    """
    if len(name) > MAX_LENGTH_OF_NAME:
        raise CreateItemError('name of item is too long')
    if len(CURRENT_ITEMS) > MAX_ITEMS_QUOTA:
        raise CreateItemError('items is full')
    return Item(name=name)
def create_for_input():
    name = input()
    try:
        item = create_item(name)
    except CreateItemError as e:
        print(f'create item failed: {err_msg}')
    else:
        print(f'item<{name}> created')

使用“抛出异常”替代“返回 (结果, 错误信息)”后,整个错误流程处理乍看上去变化不大,但实际上有着非常多不同,一些细节:

  • 新版本函数拥有更稳定的返回值类型,它永远只会返回 Item 类型或是抛出异常

  • 虽然我在这里鼓励使用异常,但“异常”总是会无法避免的让人 感到惊讶,所以,最好在函数文档里说明可能抛出的异常类型

  • 异常不同于返回值,它在被捕获前会不断往调用栈上层汇报。所以 create_item 的一级调用方完全可以省略异常处理,交由上层处理。这个特点给了我们更多的灵活性,但同时也带来了更大的风险。

Hint:如何在编程语言里处理错误,是一个至今仍然存在争议的主题。比如像上面不推荐的多返回值方式,正是缺乏异常的 Go 语言中最核心的错误处理机制。另外,即使是异常机制本身,不同编程语言之间也存在着差别。

异常,或是不异常,都是由语言设计者进行多方取舍后的结果,更多时候不存在绝对性的优劣之分。但是,单就 Python 语言而言,使用异常来表达错误无疑是更符合 Python 哲学,更应该受到推崇的。

4. 谨慎使用 None 返回值

None 值通常被用来表示“某个应该存在但是缺失的东西”,它在 Python 里是独一无二的存在。很多编程语言里都有与 None 类似的设计,比如 JavaScript 里的 null、Go 里的 nil 等。因为 None 所拥有的独特 虚无 气质,它经常被作为函数返回值使用。

当我们使用 None 作为函数返回值时,通常是下面 3 种情况。

1. 作为操作类函数的默认返回值

当某个操作类函数不需要任何返回值时,通常就会返回 None。同时,None 也是不带任何 return 语句函数的默认返回值。

对于这种函数,使用 None 是没有任何问题的,标准库里的 list.append()、 os.chdir() 均属此类。

2. 作为某些“意料之中”的可能没有的值

有一些函数,它们的目的通常是去尝试性的做某件事情。视情况不同,最终可能有结果,也可能没有结果。而对调用方来说,“没有结果”完全是意料之中的事情。对这类函数来说,使用 None 作为“没结果”时的返回值也是合理的。

在 Python 标准库里,正则表达式模块 re 下的 re.search、 re.match 函数均属于此类,这两个函数在可以找到匹配结果时返回 re.Match 对象,找不到时则返回 None。

3. 作为调用失败时代表“错误结果”的值

有时, None 也会经常被我们用来作为函数调用失败时的默认返回值,比如下面这个函数:

def create_user_from_name(username):
    """通过用户名创建一个 User 实例"""
    if validate_username(username):
        return User.from_username(username)
    else:
        return None
user = create_user_from_name(username)
if user:
    user.do_something()

当 username 不合法时,函数 create_user_from_name 将会返回 None。但在这个场景下,这样做其实并不好。

不过你也许会觉得这个函数完全合情合理,甚至你会觉得它和我们提到的上一个“没有结果”时的用法非常相似。那么如何区分这两种不同情形呢?关键在于:函数签名(名称与参数)与 None 返回值之间是否存在一种“意料之中”的暗示。

让我解释一下,每当你让函数返回 None 值时,请仔细阅读函数名,然后问自己一个问题:假如我是该函数的使用者,从这个名字来看,“拿不到任何结果”是否是该函数名称含义里的一部分?

分别用这两个函数来举例:

  • re.search():从函数名来看, search,代表着从目标字符串里去搜索匹配结果,而搜索行为,一向是可能有也可能没有结果的,所以该函数适合返回 None

  • create_user_from_name():从函数名来看,代表基于一个名字来构建用户,并不能读出一种 可能返回、可能不返回的含义。所以不适合返回 None

对于那些不能从函数名里读出 None 值暗示的函数来说,有两种修改方式。第一种,如果你坚持使用 None 返回值,那么请修改函数的名称。比如可以将函数 create_user_from_name() 改名为 create_user_or_none()。

第二种方式则更常见的多:用抛出异常(raise Exception)来代替 None 返回值。因为,如果返回不了正常结果并非函数意义里的一部分,这就代表着函数出现了“意料以外的状况”,而这正是 Exceptions 异常 所掌管的领域。

使用异常改写后的例子:

class UnableToCreateUser(Exception):
    """当无法创建用户时抛出"""
def create_user_from_name(username):
    ""通过用户名创建一个 User 实例"
    :raises: 当无法创建用户时抛出 UnableToCreateUser
    """
    if validate_username(username):
        return User.from_username(username)
    else:
        raise UnableToCreateUser(f'unable to create user from {username}')
try:
    user = create_user_from_name(username)
except UnableToCreateUser:
    # Error handling
else:
    user.do_something()

与 None 返回值相比,抛出异常除了拥有我们在上个场景提到的那些特点外,还有一个额外的优势:可以在异常信息里提供出现意料之外结果的原因,这是只返回一个 None 值做不到的。

5. 合理使用“空对象模式”

我在前面提到函数可以用 None 值或异常来返回错误结果,但这两种方式都有一个共同的缺点。那就是所有需要使用函数返回值的地方,都必须加上一个 if 或 try/except 防御语句,来判断结果是否正常。

让我们看一个可运行的完整示例:

import decimal
class CreateAccountError(Exception):
    """Unable to create a account error"""
class Account:
    """一个虚拟的银行账号"""
    def __init__(self, username, balance):
        self.username = username
        self.balance = balance
    @classmethod
    def from_string(cls, s):
        """从字符串初始化一个账号"""
        try:
            username, balance = s.split()
            balance = decimal.Decimal(float(balance))
        except ValueError:
            raise CreateAccountError('input must follow pattern "{ACCOUNT_NAME} {BALANCE}"')
        if balance < 0:
            raise CreateAccountError('balance can not be negative')
        return cls(username=username, balance=balance)
def caculate_total_balance(accounts_data):
    """计算所有账号的总余额
    """
    result = 0
    for account_string in accounts_data:
        try:
            user = Account.from_string(account_string)
        except CreateAccountError:
            pass
        else:
            result += user.balance
    return result
accounts_data = [
    'piglei 96.5',
    'cotton 21',
    'invalid_data',
    'roland $invalid_balance',
    'alfred -3',
]
print(caculate_total_balance(accounts_data))

在这个例子里,每当我们调用 Account.from_string 时,都必须使用 try/except 来捕获可能发生的异常。如果项目里需要调用很多次该函数,这部分工作就变得非常繁琐了。针对这种情况,可以使用“空对象模式(Null object pattern)”来改善这个控制流。

Martin Fowler 在他的经典著作《重构》 中用一个章节详细说明过这个模式。简单来说,就是使用一个符合正常结果接口的“空类型”来替代空值返回/抛出异常,以此来降低调用方处理结果的成本。

引入“空对象模式”后,上面的示例可以被修改成这样:

class Account:
    # def __init__ 已省略... ...
    @classmethod
    def from_string(cls, s):
        """从字符串初始化一个账号
        :returns: 如果输入合法,返回 Account object,否则返回 NullAccount
        """
        try:
            username, balance = s.split()
            balance = decimal.Decimal(float(balance))
        except ValueError:
            return NullAccount()
        if balance < 0:
            return NullAccount()
        return cls(username=username, balance=balance)
class NullAccount:
    username = ''
    balance = 0
    @classmethod
    def from_string(cls, s):
        raise NotImplementedError

在新版代码里,我定义了 NullAccount 这个新类型,用来作为 from_string 失败时的错误结果返回。这样修改后的最大变化体现在 caculate_total_balance 部分:

def caculate_total_balance(accounts_data):
    """计算所有账号的总余额
    """
    return sum(Account.from_string(s).balance for s in accounts_data)

调整之后,调用方不必再显式使用 try 语句来处理错误,而是可以假设 Account.from_string 函数总是会返回一个合法的 Account 对象,从而大大简化整个计算逻辑。

Hint:在 Python 世界里,“空对象模式”并不少见,比如大名鼎鼎的 Django 框架里的 AnonymousUser 就是一个典型的 null object。

6. 使用生成器函数代替返回列表

在函数里返回列表特别常见,通常,我们会先初始化一个列表 results=[],然后在循环体内使用 results.append(item) 函数填充它,最后在函数的末尾返回。

对于这类模式,我们可以用生成器函数来简化它。粗暴点说,就是用 yielditem 替代 append 语句。使用生成器的函数通常更简洁、也更具通用性。

def foo_func(items):
    for item in items:
        # ... 处理 item 后直接使用 yield 返回
        yield item

我在 系列第 4 篇文章“容器的门道” 里详细分析过这个模式,更多细节可以访问文章,搜索 “写扩展性更好的代码” 查看。

7. 限制递归的使用

当函数返回自身调用时,也就是 递归 发生时。递归是一种在特定场景下非常有用的编程技巧,但坏消息是:Python 语言对递归支持的非常有限。

这份“有限的支持”体现在很多方面。首先,Python 语言不支持“尾递归优化”。另外 Python 对最大递归层级数也有着严格的限制。

所以我建议:尽量少写递归。如果你想用递归解决问题,先想想它是不是能方便的用循环来替代。如果答案是肯定的,那么就用循环来改写吧。如果迫不得已,一定需要使用递归时,请考虑下面几个点:

  • 函数输入数据规模是否稳定,是否一定不会超过 sys.getrecursionlimit() 规定的最大层数限制

  • 是否可以通过使用类似 functools.lru_cache 的缓存工具函数来降低递归层数

总结

在这篇文章中,我虚拟了一些与 Python 函数返回有关的场景,并针对每个场景提供了我的优化建议。最后再总结一下要点:

  • 让函数拥有稳定的返回值,一个函数只做好一件事

  • 使用 functools.partial 定义快捷函数

  • 抛出异常也是返回结果的一种方式,使用它来替代返回错误信息

  • 函数是否适合返回 None,由函数签名的“含义”所决定

  • 使用“空对象模式”可以简化调用方的错误处理逻辑

  • 多使用生成器函数,尽量用循环替代递归

—— 推 荐 阅 读 ——

我用Python找到了隔壁蹭网妹子的QQ号

王一博、肖战  谁的颜值更高,Python告诉你

就这么简单!20行Python代码爬取腾讯视频

从零到一:手把手教你用C#开发AGV调度系统(附避坑指南) 本文详细介绍了如何使用C#开发高效的AGV调度系统,涵盖从环境搭建到核心算法实现的完整流程。重点解析了动态路径规划、多机协同等关键技术,并提供了实用的避坑指南和性能优化建议,帮助开发者快速构建工业级车辆控制调度系统。 阅读详情

相关推荐

ROS2实战:打造智能巡检机器人的关键技术与实现

本文详细介绍了基于ROS2和Navigation2构建智能巡检机器人的完整实战流程。通过设计主从协作的事件驱动架构,实现了机器人在已知地图中的自动导航、定点语音播报和环境图像采集功能。文章涵盖了从环境搭建、仿真配置到核心控制节点、语音服务与图像记录模块的代码实现,为开发者打造实用的自动巡检机器人提供了清晰的技术指南。

weixin_29031057的博客 223

计算机二级Python选择题真题第一套,计算机二级Python考试题库

计算机二级Python真题套题,计算机二级Python选择题

lemonTree的博客 1万+

STM32duino LSM6DSO驱动库:低功耗IMU工程化实践

惯性测量单元(IMU)是智能终端与工业设备实现运动感知的核心传感器,其性能关键在于数据精度、实时响应与系统功耗的协同优化。LSM6DSO作为集成加速度计与陀螺仪的六轴MEMS器件,依托片上有限状态机(FSM)和机器学习核心(MLC),支持自由落体检测、计步器、6D方向识别等硬件自治功能,显著降低主控CPU负载。在STM32平台下,通过深度耦合HAL/LL库、显式引脚管理、DMA加速SPI传输及EXTI中断协同,可实现亚毫秒级事件响应与微安级待机功耗。本文聚焦STM32duino生态中LSM6DSO驱动的工程

weixin_36304957的博客 551

python二级模拟题

PYTHON二级模拟题 一、选择题(每题1分,总分40分) 1、下列叙述中正确的是() A、算法的时间复杂度是指算法在执行过程中基本运算的次数 B.算法的时间复杂度是指算法执行所需要的时间 C、算法的时间复杂度是指算法执行的速度 D、算法复杂度是指算法控制结构的复杂程度 A 【解析】算法的时间复杂度是指执行算法所需要的计算工作量,其计算工作量是用算法所执行的基本运算次数来度量的。本题选择A选项。 2、下列叙述中正确的是() A、循环队列是队列的一种链式存储结构 B、循环队列是队列的一种顺序存储结构 C、循

qq_41405475的博客 5550

Python 列表(list)所有方法超全汇总

以上就是 Pythonlist 列表全部 11 个内置方法的完整汇总,全覆盖、无遗漏。掌握所有列表方法,基本可以应对 99% 的列表操作场景,无论是日常开发、数据分析还是算法刷题都能高效编码。

jdksjw的博客 234

SurfaceControlViewHost使用介绍

可以看到,主要用途:是把一个进程的View显示到另外一个进程里面。

chadm.xiang 1285

C语言中的函数调用和函数返回值

函数调用也就是主调函数使用被调函数,函数调用的一般形式为:函数名({实际参数表}) 对无参函数调用时则无实际参数表。 实际参数表中的参数可以是常数,变量或其他构造类型数据及表达式。 各实参之间用逗号分隔。 当在主调函数发生调用关系时 计算机会发生以下动作: 1、首先计算机自右至左依次求解主调函数实参的值。 2、系统给形参分配临时存储单元。 3、然后再自左至右把实参的值传给形参

ZHANG_kang的博客 2万+

关于三维全波电磁场仿真软件CST的安装和问题解决

百度网盘链接:https://pan.baidu.com/s/1RgWr8Qau1EzSOlh29SewFQ提取码:fzza这里是2023版本的CST,需要其他版本的uu们可以去官网或者其他人的网盘下载。

weixin_60728441的博客 3611

Python基础之函数调用、参数传递、返回值return、lambda函数等

Python基础之函数调用、参数传递、返回值return、lambda函数等

ivarwhj的博客 2626

Python 爬虫实战:Twitter 数据定向抓取(特定话题 + 用户推文爬取与分析)

在社交媒体研究、舆情监测和市场分析等领域,Twitter 数据具有极高的价值。本文将详细介绍如何使用 Python 构建一个完整的 Twitter 数据爬取系统,包括特定话题和用户推文的爬取与分析。我们将涵盖从认证到数据存储、清洗、分析和可视化的全流程。

u014481728的博客 1038

Qt 调用YOLO模型(代码)

本文介绍了如何在 Qt C++ 环境中集成 YOLO 模型进行目标检测,包括模型封装、界面设计和实时处理等关键步骤。通过这种方法,你可以快速开发出具有目标检测功能的 Qt 应用程序,应用于监控系统、机器人视觉、图像分析等多个领域。

轩宇的博客 259

Python 工匠:让函数返回结果的技巧_python调函数的结果

因为,如果返回不了正常结果并非函数意义里的一部分,这就代表着函数出现了“意料以外的状况”,而这正是 Exceptions 异常 所掌管的领域。让我解释一下,每当你让函数返回 None 值时,请仔细阅读函数名,然后问自己一个问题:假如我是该函数的使用者,从这个名字来看,“拿不到任何结果”是否是该函数名称含义里的一部分?与 None 返回值相比,抛出异常除了拥有我们在上个场景提到的那些特点外,还有一个额外的优势:可以在异常信息里提供出现意料之外结果的原因,这是只返回一个 None 值做不到的。

2501_90424990的博客 1975

如何借助GPT- 6 写好一篇论文:从引言到参考文献完整步骤(附专业提示词)

七哥就结合这篇文章的写作思路,依次拆解引言、方法、结果、讨论、摘要、标题和参考文献分别应该怎么写,同时也聊聊,在每一个环节里,我们可以怎样合理借助 GPT-6,让论文写作变得更清晰、更高效。可以和七哥交流学术写作或Gemini、GPT、Claude 等大模型 学术实操相关问题,多多交流,相互成就,共同进步。8、不修改、不补写、不猜测任何样本量、阈值、剂量、设备型号、参数或统计方法,所有缺失但影响方法完整性的信息统一标记为【待作者确认】、检查方法中设定的每一个分析项目能否在后续结果章节找到对应位置。

智能AI让学术科研更容易 110

5-Python 工匠:让函数返回结果的技巧

在这篇文章中,我虚拟了一些与 Python 函数返回有关的场景,并针对每个场景提供了我的优化建议。让函数拥有稳定的返回值,一个函数只做好一件事使用定义快捷函数抛出异常也是返回结果的一种方式,使用它来替代返回错误信息函数是否适合返回 None,由函数签名的“含义”所决定使用“空对象模式”可以简化调用方的错误处理逻辑多使用生成器函数,尽量用循环替代递归看完文章的你,有没有什么想吐槽的?请留言或者在项目 Github Issues告诉我吧。>>>下一篇【6.异常处理的三个好习惯】

wujianyouhun的专栏 1219

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

mysql函数返回结果集_Python 工匠:让函数返回结果的技巧

序言毫无疑问,函数是 Python 语言里最重要的概念之一。在编程时,我们将真实世界里的大问题分解为小问题,然后通过一个个函数交出答案。函数即是重复代码的克星,也是对抗代码复杂度的最佳武器。如同大部分故事都会有结局,绝大多数函数也都是以返回结果作为结束。函数返回结果的手法,决定了调用它时的体验。所以,了解如何优雅的让函数返回结果,是编写好函数的必备知识。Python 的函数返回方式Python 函...

weixin_39954569的博客 331

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

python return_Python 工匠:让函数返回结果的技巧

原标题:Python 工匠:让函数返回结果的技巧作者:piglei (本文来自作者投稿) 毫无疑问,函数是 Python 语言里最重要的概念之一。在编程时,我们将真实世界里的大问题分解为小问题,然后通过一个个函数交出答案。函数即是重复代码的克星,也是对抗代码复杂度的最佳武器。如同大部分故事都会有结局,绝大多数函数也都是以返回结果作为结束。函数返回结果的手法,决定了调用它时的体验。所以,了解如何优雅...

weixin_39854951的博客 352

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

python先返回再处理_Python 工匠:让函数返回结果的技巧

原标题:Python 工匠:让函数返回结果的技巧毫无疑问,函数是 Python 语言里最重要的概念之一。在编程时,我们将真实世界里的大问题分解为小问题,然后通过一个个函数交出答案。函数即是重复代码的克星,也是对抗代码复杂度的最佳武器。如同大部分故事都会有结局,绝大多数函数也都是以返回结果作为结束。函数返回结果的手法,决定了调用它时的体验。所以,了解如何优雅的让函数返回结果,是编写好函数的必备知识。...

weixin_39535283的博客 640

create报错不是函数_Python 工匠:让函数返回结果的技巧

花下猫语:敢用“工匠”来给自己的系列文章命名,这样的作者就表明了自己的态度与信心——他真正关心代码的味道,他真正关心弯弯曲曲的纹理,并且会认真剖刻杂余,最后雕出件优雅的作品。Python工匠是少有的优秀的专注于 Python 技术的系列文章,目前更新到了第 5 篇,正是我要分享给大家的这篇。事实上,我们之前也转载过一篇,恐怕这以后会形成一个传统。有幸认识了作者本人,原来他来自腾讯这个大厂...

weixin_29349409的博客 209

Python 工匠:让函数返回结果的技巧_python调函数的结果(1)

Python崛起并且风靡,因为优点多、应用领域广、被大牛们认可。学习 Python 门槛很低,但它的晋级路线很多,通过它你能进入机器学习、数据挖掘、大数据,CS等更加高级的领域。Python可以做网络应用,可以做科学计算,数据分析,可以做网络爬虫,可以做机器学习、自然语言处理、可以写游戏、可以做桌面应用…Python可以做的很多,你需要学好基础,再选择明确的方向。这里给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助!

m0_58269070的博客 388
上一篇: 2019最烂密码榜单出炉,教你设置神级密码!
下一篇: 学富五车的你,敢来迎战Python开发的成语接龙游戏吗?
菜鸟学Python
博客等级 码龄9年 8063粉丝 571原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值